lima icon indicating copy to clipboard operation
lima copied to clipboard

Remove indirect dependency on github.com/mailru/easyjson

Open alexandear opened this issue 7 months ago • 18 comments

Description

This project has an indirect dependency on github.com/mailru/easyjson, a Go library with maintainers based in Russia and affiliated with VK Group. VK Group has known ties to the Russian government and a history of cooperating with Russian security services, including sharing user data.

According to the Hunted Labs report, "The Russian Open Source Project That We Can’t Live Without", this dependency poses a significant supply chain risk. A compromised easyjson library could lead to severe consequences, including:

  • Supply chain backdoors
  • Remote code execution
  • Espionage
  • Data exfiltration
  • Potential "kill switch" functionality

To mitigate these risks, I propose to remove this indirect dependency.

Dependencies that relies on easyjson (updated based on the discussion below):

alexandear avatar May 10 '25 11:05 alexandear

The ordered map functionality is only used by the genschema at the moment, so can be easily avoided.

This also means that the code is not in the path of anyone not using the limactl generate-jsonschema

EDIT: Oops, spoke too soon. It is imported from https://github.com/invopop/jsonschema

github.com/lima-vm/lima/cmd/limactl
github.com/invopop/jsonschema
github.com/wk8/go-ordered-map/v2
github.com/mailru/easyjson/jwriter

It is still not used by other commands, but would be a bit harder to remove completely

afbjorklund avatar May 10 '25 15:05 afbjorklund

Apparently we already have another OrderedMap in the dependencies, that is used by yqutil.

github.com/elliotchance/orderedmap

EDIT: this other library is older (go1.18) and not generic, so it is not a drop-in replacement

invalid operation: orderedmap.OrderedMap[string, *Schema] (orderedmap.OrderedMap is not a generic type)

afbjorklund avatar May 10 '25 15:05 afbjorklund

github.com/wk8/go-ordered-map is the only dependency that relies on easyjson.

Depended by Kubernetes too:

$ go mod why github.com/mailru/easyjson/jlexer
# github.com/mailru/easyjson/jlexer
github.com/lima-vm/lima/pkg/guestagent/kubernetesservice
k8s.io/client-go/kubernetes
k8s.io/client-go/discovery
k8s.io/client-go/openapi
k8s.io/kube-openapi/pkg/spec3
github.com/go-openapi/swag
github.com/mailru/easyjson/jlexer
  • https://github.com/go-openapi/swag/issues/68

AkihiroSuda avatar May 10 '25 15:05 AkihiroSuda

this dependency poses a significant supply chain risk

We have been locking the dependency with go.sum, and the current version https://github.com/mailru/easyjson/tree/5e854fb809ec83ff18eb74554fd5c693e28eaadb apparently does not seem to contain suspicious codes: https://github.com/lima-vm/lima/blob/ad8ac1cbc58b3fe3fb2078409d2f649eb0e9cf51/go.sum#L174-L175

$ go mod vendor
$ cd vendor/github.com/mailru/easyjson
$ find .
.
./LICENSE
./jwriter
./jwriter/writer.go
./jlexer
./jlexer/error.go
./jlexer/bytestostr_nounsafe.go
./jlexer/bytestostr.go
./jlexer/lexer.go
./buffer
./buffer/pool.go

We also experimentally support gomodjail to make dependencies less privileged: https://github.com/lima-vm/lima/blob/ad8ac1cbc58b3fe3fb2078409d2f649eb0e9cf51/go.mod#L1

gomodjail is still opt-in though.

AkihiroSuda avatar May 10 '25 15:05 AkihiroSuda

For a while maybe we should set easyjson_nounsafe ?

https://github.com/mailru/easyjson/blob/fe2707c07ac01dd7377350e8edf4f574705358bf/jlexer/bytestostr_nounsafe.go#L4

AkihiroSuda avatar May 10 '25 15:05 AkihiroSuda

I have no problem with removing the dependency from our code base as much as reasonably possible, but it will not be removed from Kubernetes; CNCF has ruled this to be a non-issue:

  • https://github.com/cncf/foundation/issues/550
  • https://github.com/kubernetes/kubernetes/issues/117553

So as long as we have a dependency on the k8s client library, we will have a dependency on easyjson as well.

jandubois avatar May 10 '25 19:05 jandubois

So as long as we have a dependency on the k8s client library, we will have a dependency on easyjson as well.

I believe the only dependency on the k8s client libs is in the guest-agent code monitoring port changes. We should be able to replace this with kubectl get --watch, which will also significantly reduce the size of the guest-agents.

Of course kubectl would still rely on easyjson, but that is out of our control.

jandubois avatar May 10 '25 20:05 jandubois

What about foxcpp/go-mockdns?

msimkunas avatar Aug 01 '25 16:08 msimkunas

What about foxcpp/go-mockdns?

What about it? I don't understand the point of this comment.

jandubois avatar Aug 01 '25 16:08 jandubois

Sorry for being brief. AFAIK the repository is owned by someone who is associated with VK as well, at least based on their description.

msimkunas avatar Aug 01 '25 16:08 msimkunas

I see. It is only used in a single place in a test, so doesn't have the same level of supply-chain risk.

https://github.com/lima-vm/lima/blob/c1b84967f0c95f166ec4361616ed11773aab76d0/pkg/hostagent/dns/dns_test.go#L29-L44

Feel free to submit a PR to replace it with an alternative, if you find one.

jandubois avatar Aug 01 '25 17:08 jandubois

The test dependencies are not included in the final build, correct? It's not the same risk but having it in the pipelines is not ideal. Unless it's pinned to a known safe version and is not updated by dependabot without review.

msimkunas avatar Aug 01 '25 17:08 msimkunas

The test dependencies are not included in the final build, correct?

Correct

It's not the same risk but having it in the pipelines is not ideal.

That's why I suggested to replace it, if you happen to know an alternative.

Unless it's pinned to a known safe version and is not updated by dependabot without review.

We could exclude it from dependabot.yml with something like this:

   ignore:
   # don't update go-mockdns without a full audit of all changes
   - dependency-name: "github.com/foxcpp/go-mockdns"
     update-types:
     - "version-update:semver-major"
     - "version-update:semver-minor"
     - "version-update:semver-patch"

jandubois avatar Aug 01 '25 17:08 jandubois

What about forking it/including it in the project? It's not a large package.

msimkunas avatar Aug 01 '25 17:08 msimkunas

What about forking it/including it in the project? It's not a large package.

Not keen on vendoring other projects. Functionally it would be identical to just blocking it from dependabot. The package didn't have any functional changes in over 3 years.

jandubois avatar Aug 01 '25 17:08 jandubois

Would you consider blocking easyjson upgrades as well?

msimkunas avatar Aug 01 '25 17:08 msimkunas

Would you consider blocking easyjson upgrades as well?

I don't know if this is possible, as it is only an indirect dependency we get via Kubernetes. It is not updated directly via our dependabot settings, but will be brought in when we update Kubernetes dependencies, and if they have bumped easyjson. So we kind of have to rely on their due diligence.

jandubois avatar Aug 01 '25 17:08 jandubois

FYI, go-openapi/swag seems to have removed this dependency: https://github.com/go-openapi/swag/commit/f344ab5d42c5bbcd5ed2d79c9d14bfdae3817260

msimkunas avatar Nov 09 '25 15:11 msimkunas