Skip to content

CHEF-37625 - Add concurrent-ruby version floor to chef-server-ctl Gemfile - #4231

Open
lbakerchef wants to merge 4 commits into
mainfrom
CHEF-37625/lbaker
Open

CHEF-37625 - Add concurrent-ruby version floor to chef-server-ctl Gemfile#4231
lbakerchef wants to merge 4 commits into
mainfrom
CHEF-37625/lbaker

Conversation

@lbakerchef

Copy link
Copy Markdown
Contributor

Summary

Adds an explicit concurrent-ruby version floor (>= 1.3.7) directly to src/chef-server-ctl/Gemfile. concurrent-ruby is a real (transitive, via chef/knife/berkshelf) dependency, currently resolving to 1.3.8 — already above the floor, so this adds an explicit safety net rather than changing the resolved version.

Declared as a bare floor rather than routed through the SafeVersions/resolve_safe_version.call mechanism (unlike rack/rexml directly above it in the same file): that mechanism exists to keep a cleanup-recipe threshold (ruby_gems_cleanup.rb, in chef-server-omnibus-config) and a Gemfile floor from drifting apart for the same gem. concurrent-ruby has no on-disk cleanup consumer (no ticket or test/scan finding has established that need), so there's no second consumer for that mechanism to keep in sync — see the companion chef-server-omnibus-config PR (documentation-only, same ticket) for the fuller rationale.

Jira

https://progresssoftware.atlassian.net/browse/CHEF-37625

CVEs closed

GHSA-6wx8-w4f5-wwcr, GHSA-h8w8-99g7-qmvj (high), GHSA-wv3x-4vxv-whpp (Dependabot alerts 377, 380, 383)

Stacked branch note

This PR is stacked on top of CHEF-33469/lbaker (#4227, CHEF-35182 — the net-imap fix), which has not yet merged. As a result, this PR's diff currently includes #4227's commits in addition to this ticket's own change (the concurrent-ruby floor).

Please review only the top commit (the concurrent-ruby floor addition) — the rest belongs to #4227 and is already under review there.

Merge order matters for attribution, not final content: since this branch is a superset of #4227's tip, the end-state file content on main is identical regardless of which PR merges first. However, #4227 should merge first — merging this PR first would land #4227's still-unreviewed commits under this PR's merge event (bypassing #4227's own review), and with squash-merge could fold #4227's changes into this PR's squash commit instead of preserving #4227's own attribution.

Testing

Verified via Docker (ruby:3.1.3, bundler 2.3.27) with the real upstream safe_versions.rb (from chef-server-omnibus-config, no concurrent-ruby constant) copied temporarily into place, mimicking the omnibus build's copy step: the resulting Gemfile.lock is byte-identical to the pre-change lockfile — both the previous resolve_safe_version.call-indirected floor and this bare floor interpolate to the exact same >= 1.3.7 requirement, so this is a zero-regression mechanism change. concurrent-ruby remains resolved at 1.3.8. Full chef-server-ctl rspec suite (79/0) previously verified against the functionally-equivalent indirected version; the bare-floor refactor produces no lockfile change, so no dependency resolution is affected.

@lbakerchef
lbakerchef requested review from a team as code owners August 17, 2026 16:34
@lbakerchef
lbakerchef force-pushed the CHEF-37625/lbaker branch 2 times, most recently from 5a75ed1 to 21181f3 Compare August 18, 2026 14:13
Add explicit rack/rexml version floors to the three Gemfiles here
that pull in chef and/or chef-zero (chef-server-ctl, oc-id,
oc-chef-pedant), sourced dynamically from the same
SafeVersions::MINIMUM_SAFE_RACK_VERSION / MINIMUM_SAFE_REXML_VERSION
constants that ruby_gems_cleanup.rb enforces on upgrade, reached via
the omnibus/ submodule's libraries/safe_versions.rb (bumped in the
prior commit). This makes the safety floor a single source of
truth instead of two independently maintained values that can
drift apart.

- src/chef-server-ctl/Gemfile: new rack + rexml floors (had none).
- src/oc-id/Gemfile: replaced the previous static
  `gem 'rack', '>= 3.2.4'` with the dynamic floor; added a new
  rexml floor (had none).
- oc-chef-pedant/Gemfile: new rack floor only (rexml isn't in its
  resolved dependency graph).

Each Gemfile wraps the require_relative in begin/rescue LoadError
and fails open (warns, defaults to no floor) if the submodule isn't
checked out or the file can't otherwise be reached, or if the
expected constants aren't defined/are blank -- so a developer who
hasn't run `git submodule update --init` still gets a working
`bundle install`, just without the extra floor enforced. A genuine
bug in safe_versions.rb's own Ruby (syntax error, etc.) is not
swallowed and will still fail the build loudly, by design.

Signed-off-by: Lincoln Baker <51833247+lbakerchef@users.noreply.github.com>

extend oc-id's rack/rexml Gemfile floor pattern to net-imap (CHEF-35182)

Add a net-imap version floor to oc-id's Gemfile using the same
resolve_safe_version.call(:CONSTANT) pattern already used for
rack/rexml, sourced from omnibus-config's safe_versions.rb (the
same file ruby_gems_cleanup.rb enforces on upgrade):

  gem 'net-imap', ">= #{resolve_safe_version.call(:NET_IMAP_FIX_VERSION)}"

net-imap isn't a direct oc-id dependency -- it's pulled in
transitively via mail -- but CVE-2025-XXXXX (net-imap response
injection) affects versions below 0.5.14 (Ruby < 3.2) or 0.6.4
(Ruby >= 3.2). NET_IMAP_FIX_VERSION resolves to whichever floor
applies to the Ruby this Gemfile is bundled under, so `bundle
install` refuses to resolve a vulnerable net-imap regardless of
what mail or any other dependency would otherwise pull in.

Comment updated to mention net-imap alongside rack/rexml and to
point at NET_IMAP_FIX_VERSION specifically, since (unlike the
rack/rexml floors) it's a computed value rather than a fixed one --
see safe_versions.rb for why.

Companion change in chef-server-omnibus-config (commit f38c231,
"extend safe-versions floors to net-imap") adds the
NET_IMAP_FIX_VERSION_0_4/_0_5/_0_6 constants, the generic
NET_IMAP_FIX_VERSION resolution, and generalizes ruby_gems_cleanup.rb's
vulnerable-gem sweep to cover net-imap; that repo's submodule
pointer is bumped in a separate commit here.

Signed-off-by: Lincoln Baker <51833247+lbakerchef@users.noreply.github.com>
Signed-off-by: Lincoln Baker <51833247+lbakerchef@users.noreply.github.com>
Add an explicit concurrent-ruby version floor to src/chef-server-ctl/Gemfile.
concurrent-ruby is a real (transitive, via chef/knife/berkshelf) dependency,
currently resolving to 1.3.8 -- already above the floor, so this adds an
explicit safety net rather than changing the resolved version. Three CVEs
affect versions below 1.3.7 (GHSA-6wx8-w4f5-wwcr, GHSA-h8w8-99g7-qmvj [high],
GHSA-wv3x-4vxv-whpp; Dependabot alerts 377, 380, 383), all agreeing on the
same minimum patched version.

Declared as a bare floor rather than routed through omnibus-config's
safe_versions.rb/resolve_safe_version.call (unlike rack/rexml above): that
mechanism exists to keep a cleanup-recipe threshold (ruby_gems_cleanup.rb)
and a Gemfile floor from drifting apart for the same gem -- it is not a
generic place to declare any gem's minimum version. CHEF-37625 is scoped
only to Dependabot's Gemfile.lock scanning, which this floor alone fully
and permanently resolves; there is no ticket or on-disk test/scan finding
establishing a cleanup need for concurrent-ruby, so there is no second
consumer for safe_versions.rb to keep in sync with this floor. See the
companion documentation added to chef-server-omnibus-config's
safe_versions.rb (same ticket) for the fuller explanation of when a
constant belongs there vs. a bare Gemfile floor like this one.

CHEF-37625

Signed-off-by: Lincoln Baker <51833247+lbakerchef@users.noreply.github.com>
…ifrost pedant

Signed-off-by: Lincoln Baker <51833247+lbakerchef@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant