Lock the checksum of Bundler itself in the lockfile#9366
Lock the checksum of Bundler itself in the lockfile#9366Edouard-chin wants to merge 2 commits intoruby:masterfrom
Conversation
- ### Problem With the Bundler autoswitch feature, system Bundler may install a `bundler.gem` that matches the Gemfile.lock. The `bundler.gem` that gets downloaded is like any other gems, but its treated differently (it doesn't appear in the Gemfile specs and we also don't lock its checksum). If for any reason Bundler itself gets compromised, it's a security concern. ### Details I'd like to introduce this change into two separate changes for easier reviews. The first (this commit) only produce the checksum in the lockfile, nothings consumes it or verify it yet. The second patch will make sure that whenever the Bundler auto-install kicks in, Bundler will verify that the locked checksum matches the Bundler version being downloaded and installed. ### Solution Overall the solution here is similar to how checksums are already generated for other gems. However, the `bundler` gem comes from a different source (the `Bundler::Source::Metadata`) and so it needs to be handled slightly differently. A big part ot the change is test related. Instead of having to modify all tests that assert the state of the lockfile (which will be broken now, since the lockfile includes the Bundler checksum), I opted to automatically include the checksum whenever the helper metod `checksums_section` is called.
| require "rubygems/package" | ||
|
|
||
| bundler_spec = definition.sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last | ||
| return [] unless File.exist?(bundler_spec.cache_file) |
There was a problem hiding this comment.
I unfortunately need to have this File.exist?(bundler_spec.cache_file) condition here due to the way our rspec is setup. At the very beginning of the a test process, we install test dependencies and we use the local copy of bundler for that. We activate the bundler spec in a weird way, but there is no associated bundler.gem tarball, so we can't compute the checksum.
Note that this condition is only needed to install the dependencies of bundler itself. It doesn't affect tests itself (because we build a bundler.gem each time a test starts).
|
|
||
| CHECKSUMS | ||
| ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 | ||
| bundler (4.1.0.dev) sha256=d2562ecdca5da9c15b46fedd7dbc109fca4938895942e34564c974ee6eabd5f8 |
There was a problem hiding this comment.
Hmm, I just saw that CI was complaining because the lockfile for development purposes aren't up to date, so I modified them.
This may be annoying though, as it means any changes in Bundler we make will change the checksum and we'd need to update them by running rake version:update_locked_bundler.
I have to think of a solution
There was a problem hiding this comment.
Maybe add option to opt-out of this feature somehow? Alternatively skip it for dev/pre versions? I think similar gate is around auto-switch/install trampoline and call for update features. They are disabled if dev Bundler/RubyGems is detected.
There was a problem hiding this comment.
Oh nice! Good idea to skip for dev/pre versions, thanks for the suggestion !
What was the end-user or developer problem that led to this PR?
I'd like to be able to lock the checksum of the
bundlergem itself. I find strange that all gems get their checksum locked, but bundler itself (which is the only gem that every application will need to install due to the auto-switch feature) isn't getting locked.I think this is a security vulnerability and I'd like to fix this.
With this patch, the lockfile will look like this:
What is your fix for the problem, implemented in this PR?
Details
I'd like to introduce this change into two separate changes for easier reviews. The first (this commit) only produce the checksum in the lockfile, nothings consumes it or verify it yet.
The second patch will make sure that whenever the Bundler auto-install kicks in, Bundler will verify that the locked checksum matches the Bundler version being downloaded and installed.
Though, please let me know if you'd prefer me doing the whole thing in just one PR.
Solution
Overall the solution here is similar to how checksums are already generated for other gems. However, the
bundlergem comes from a different source (theBundler::Source::Metadata) and so it needs to be handled slightly differently.A big part ot the change is test related. Instead of having to modify all tests that assert the state of the lockfile (which will be broken now, since the lockfile includes the Bundler checksum), I opted to automatically include the checksum whenever the helper metod
checksums_sectionis called.I'll add a few comments on the code directly for parts that may not be obvious.
Make sure the following tasks are checked