Potential risk of fetching dependencies from Git

116 views
Skip to first unread message

Bram Verburg

unread,
Jun 27, 2016, 2:35:06 PM6/27/16
to elixir-lang-core
Hi,

The other day I wrote a post on security best-practices around dependencies (https://blog.voltone.net/post/5). One of the issues I raised was the risk of unexpected code execution when pulling in dependencies from Git repositories: "mix deps.get" recursively installs any sub-dependencies, and this involves evaluating the downloaded mix.exs file.

On the one hand, the choice to embed 3rd party code into your application means you put (some) trust in the provider of that code. On the other hand, even a trusted developer can become the target of an attack that tries to inject malicious code into other people's applications: that's why, for instance, Hex protects the integrity of packages using HTTPS and checksums.

Given the risk of a Git repo being compromised, or even a developer going bad, downloading and immediately executing code from a repository seems like a bad idea. Users should have the possibility to review the downloaded code before deciding to trust it. Right now, running "mix deps.get" on a project with Git dependencies is technically a violation of my employer's security policies, since it could introduce malware or lead to data being harvested from the corporate network.

I'd love to hear your opinion (since I didn't get around to adding comments to my blog engine):

1. Should we be worried about this at all? When I pull in a Ruby Gem from a Git repo (as opposed to the RubyGems repositories) the same thing happens, right? And anyway, most dependencies are Hex packages nowadays...

2. Should we warn users about this in the Mix documentation? That seems a bit lame: to point out a security risk, but without offering any tooling to mitigate that risk other than letting the user manually inspect each repository (recursively) prior to running "mix deps.get"

3. Should we disable the automatic evaluation of "mix.exs" files fetched from Git (or other SCMs that don't have Hex-like dependency metadata), and instead let the user explicitly run "mix deps.get <git-based-dep>" to trigger evaluation of that dependency's "mix.exs" file to fetch sub-dependencies? Or ask interactively whether to go ahead, the way "mix phoenix.new" asks whether to fetch Mix and NPM dependencies? In both cases we could add an override flag "--force" to restore the current behaviour for users who understand and accept the risk.

Thanks,

Bram

Eric Meadows-Jönsson

unread,
Jun 27, 2016, 5:38:34 PM6/27/16
to elixir-l...@googlegroups.com
First of I'd like you to thank you Bram for looking into potential security issues and starting discussions about what you find. We need more people doing that.

Also, your discussions with the core team and your blog post made me find this issue https://github.com/hexpm/hex/issues/243 in the Hex client where the checksums will not give full protection for locked dependencies.

This is a difficult subject, because as it usually is with security you have to weigh the safety concerns against usability concerns. You can give give users all the tools for verifying all the dependencies they use but if it is not practical to do so in their normal workflow they will simply not use the tools we provide them.

First we have to consider the number of users that would verify dependencies fetched from git repositories to protect themselves against compromised git repositories. My bet is that it is a small number (because of the time you have to invest in verifying the code), so I don't think we should change any defaults because that would impair the workflow for the majority of developers. But I do think we should add an option that only fetches one level of dependencies without evaluating their mix.exs for the developers that do care about this.

Unfortunately, until we have some way of signing of code and a (practical) way of verifying the signatures I don't think we can have a great solution for this issue. And even then signing keys can be compromised, so in the end the only way to fully protect yourself is to fetch dependencies in a sandbox, manually vet all the code and lock them to your lockfile.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/395b50f9-7918-403e-a368-a14fcb966f8f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Eric Meadows-Jönsson

Bram Verburg

unread,
Jun 28, 2016, 3:33:08 AM6/28/16
to elixir-lang-core
Hi Eric,

Thanks for your feedback. It's definitely a UX versus security trade-off.

Personally I dislike those tools that tell you to install by copying "curl http://example.net/install.sh | sh" into the terminal (HomeBrew, I'm looking at you), and in many ways this is very similar. Except that in the curl example it should be obvious what is being done, whereas people might not realise what's going on during "mix deps.get". Especially for beginners I'd rather err on the side of caution: show a message explaining why the sub-dependencies were not installed and point to the docs for more info.

On the other hand, it seems no one is particularly concerned about Ruby .gemspec files doing the same thing (someone please correct me if I'm wrong, it's been a while since I've used Ruby). But then again, Ruby has always preferred the path of least resistance for the developer. In other areas Elixir tries to improve over Ruby by looking beyond instant developer gratification, with the "explicit is better than implicit" approach. I think the same could be applied here. But in the end that's up to the core team, perhaps based on community consensus.

Anyway, I could start with a PR that adds a flag, and we can continue the discussion on what should be the default in the PR.

Thanks,

Bram

Eric Meadows-Jönsson

unread,
Jun 30, 2016, 8:10:42 AM6/30/16
to elixir-l...@googlegroups.com
A PR for a flag would be appreciated.


For more options, visit https://groups.google.com/d/optout.



--
Eric Meadows-Jönsson

José Valim

unread,
Jun 30, 2016, 9:01:00 AM6/30/16
to elixir-l...@googlegroups.com
One of my concerns by adding a flag is that we may end-up like EU's Cookie policy where nobody actually read the warning, they will just end-up passing the flag. So at this point I would prefer the flag to be opt-in so people enable it explicitly when they want to be double sure no execution happens on deps.get, for example, during deployments.



José Valim
Skype: jv.ptec
Founder and Director of R&D

Reply all
Reply to author
Forward
0 new messages