rubygems / rubygems

Library packaging and distribution for Ruby.
https://rubygems.org/
Other
3.68k stars 1.74k forks source link

Gem::Specification#executables should not accept Strings containing spaces #6287

Open postmodern opened 1 year ago

postmodern commented 1 year ago

Describe the problem as clearly as you can

I believe that there should be additional validations on Gem::Specification#executables to not allow executable names that contain spaces. This could potentially lead to command injection in other tools which parse the executable names of gemspecs.

Post steps to reproduce the problem

test.gemspec:

Gem::Specification.new do |spec|
  spec.name          = "test"
  spec.version       = '0.0.0'
  spec.authors       = ['test']
  spec.email         = ["test@example.com"]
  spec.summary       = %q{Test gem}
  spec.description   = %q{This is a test gem.}
  spec.homepage      = "https://github.com/postmodern/test/tree/master/ruby/gem"
  spec.license       = "MIT"

  spec.files         = ["test.gemspec", "bin/echo hax"]
  spec.executables   = ['echo hax']
  spec.require_paths = ["lib"]
end

Which command did you run?

$ mkdir bin
$ echo '#!/usr/bin/env ruby' > "bin/echo hax"
$ chmod +x "bin/echo hax"
$ gem build test.gemspec

What were you expecting to happen?

A validation error about the command containing a space.

What actually happened?

  Successfully built RubyGem
  Name: test
  Version: 0.0.0
  File: test-0.0.0.gem

Run gem env and paste the output below

RubyGems Environment:
  - RUBYGEMS VERSION: 3.4.1
  - RUBY VERSION: 3.2.0 (2022-12-25 patchlevel 0) [x86_64-linux]
  - INSTALLATION DIRECTORY: /home/postmodern/.gem/ruby/3.2.0
  - USER INSTALLATION DIRECTORY: /home/postmodern/.gem/ruby/3.2.0
  - RUBY EXECUTABLE: /opt/rubies/ruby-3.2.0/bin/ruby
  - GIT EXECUTABLE: /usr/local/bin/git
  - EXECUTABLE DIRECTORY: /home/postmodern/.gem/ruby/3.2.0/bin
  - SPEC CACHE DIRECTORY: /home/postmodern/.local/share/gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: /opt/rubies/ruby-3.2.0/etc
  - RUBYGEMS PLATFORMS:
     - ruby
     - x86_64-linux
  - GEM PATHS:
     - /home/postmodern/.gem/ruby/3.2.0
     - /opt/rubies/ruby-3.2.0/lib/ruby/gems/3.2.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => true
     - :bulk_threshold => 1000
  - REMOTE SOURCES:
     - https://rubygems.org/
  - SHELL PATH:
     - /home/postmodern/.gem/ruby/3.2.0/bin
     - /opt/rubies/ruby-3.2.0/lib/ruby/gems/3.2.0/bin
     - /opt/rubies/ruby-3.2.0/bin
     - /home/postmodern/.local/bin
     - /home/postmodern/bin
     - /usr/local/bin
     - /usr/local/sbin
     - /usr/bin
     - /usr/sbin
     - /var/lib/snapd/snap/bin
     - /home/postmodern/bin
     - /home/postmodern/bin
postmodern commented 1 year ago

It also appears that it's possible to put single quotes in the executable name, which would be useful for escaping quoted values.

Gem::Specification.new do |spec|
  spec.name          = "test"
  spec.version       = '0.0.0'
  spec.authors       = ['test']
  spec.email         = ["test@example.com"]
  spec.summary       = %q{Test gem}
  spec.description   = %q{This is a test gem.}
  spec.homepage      = "https://github.com/postmodern/test/tree/master/ruby/gem"
  spec.license       = "MIT"

  spec.files         = ["test.gemspec", "bin/'escape"]
  spec.executables   = ["'escape"]
  spec.require_paths = ["lib"]
end