Skip to content

Add executables and bindir validation to the gem installer#9595

Merged
hsbt merged 4 commits into
masterfrom
strengthen-installer-validation
Jun 5, 2026
Merged

Add executables and bindir validation to the gem installer#9595
hsbt merged 4 commits into
masterfrom
strengthen-installer-validation

Conversation

@hsbt
Copy link
Copy Markdown
Member

@hsbt hsbt commented Jun 4, 2026

What is your fix for the problem, implemented in this PR?

Gem::Installer#verify_spec now validates spec.executables and spec.bindir during pre-install checks, requiring executables to be plain basenames and bindir to stay within the gem directory.

The generated wrapper script also escapes the executable name so quotes in the name cannot change the generated Ruby.

Make sure the following tasks are checked

hsbt and others added 3 commits June 4, 2026 16:53
Reject executables that are not plain basenames during pre-install checks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reject a bindir that resolves outside the gem directory during pre-install
checks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Escape the executable name interpolated into the generated wrapper so a
name containing quotes cannot change the generated Ruby.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 4, 2026 08:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR strengthens RubyGems installation safety by validating spec.executables and spec.bindir during Gem::Installer#verify_spec, and by escaping executable names when generating wrapper scripts to prevent Ruby code injection via crafted executable names.

Changes:

  • Add pre-install validation rejecting invalid spec.executables (must be plain basenames) and spec.bindir (must remain within the gem directory).
  • Escape ' and \ in wrapper script executable names in app_script_text.
  • Add regression tests covering malicious executables/bindir values and wrapper escaping behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
test/rubygems/test_gem_installer.rb Adds tests for executable-name escaping in wrappers and for rejecting malicious executables/bindir during pre-install checks.
lib/rubygems/installer.rb Implements new verify_spec validations for executables and bindir, and escapes executable names in generated wrapper scripts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/rubygems/installer.rb
Comment on lines +720 to +724
expanded_gem_dir = File.expand_path(gem_dir)
expanded_bindir = File.expand_path(File.join(gem_dir, spec.bindir))
unless expanded_bindir == expanded_gem_dir || expanded_bindir.start_with?("#{expanded_gem_dir}/")
raise Gem::InstallError, "#{spec} has an invalid bindir"
end
Comment thread lib/rubygems/installer.rb Outdated
Comment on lines +716 to +717
if spec.executables.any? {|name| name != File.basename(name) || /\A\.\.?\z|\R/.match?(name) }
raise Gem::InstallError, "#{spec} has an invalid executable"
A non-String executable name or bindir previously raised TypeError from
File.basename or File.join. Guard the type so verify_spec raises
Gem::InstallError instead of aborting with an unexpected exception.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hsbt hsbt merged commit 4fa3f04 into master Jun 5, 2026
133 of 135 checks passed
@hsbt hsbt deleted the strengthen-installer-validation branch June 5, 2026 01:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants