OSS suply chain security for Ruby gems

mensfeld.github.io/oss-supply-chain-security-for-ruby

⚠️ Disclaimer

🙏

  • It's my first remove presentation, so please be forgiving
  • You can write questions while I'm talking in the Zoom chat window
  • I have a demo section so sorry if won't work 😂

⚠️ Disclaimer

  • There are more challenges related to Ruby gems than those presented
  • Some of the tools I will be showing aren't yet publicly available, but I'm working on it
  • Some of the things presented here will be soon accessible directly from RubyGems

$ whoami --code

Maciej Mensfeld

  • Software Engineer / Architect
  • Karafka creator
  • OSS contributor (~14 years with Ruby)

$ whoami --work

End-to-end solution to prevent threats beyond account takeover

Kraków Ruby Users Group organizer
  • One of the biggest Ruby communities in Europe
  • Over 1400 members
  • 60-150 attendees per event
  • One meeting per month with 2-3 tech talks
  • 23 sponsors

krk-rb.pl

$ whoami --contact

github: github.com/mensfeld
www: mensfeld.pl
twitter: @maciejmensfeld
e-mail: maciej@mensfeld.pl

$ whoami --not

What do I hope to leave you with

RubyGems shouldn't be used lightly, without being aware of the downsides and risks. This session should help you understand risks related to using RubyGems and OSS libraries. It should give you also a bit of knowledge on how to countermeasure those risks and how to stay safe investing a sane amount of time.

Agenda

  • What is RubyGems
  • Risks types & attacks
  • Countermeasures

RubyGems

RubyGems is a package manager for the Ruby programming language.

Development of RubyGems started in November 2003 and was released to the public on March 14, 2004, or Pi Day 2004.

It was created by Chad Fowler and Richard Kilmer during RubyConf 2004

  • Total gems: 161 800
  • Total users: 149 192
  • Total downloads: 58 451 888 216
  • Downloads per second: 71

+

Risks types & attacks

Please watch my Taking over a Ruby gem RubyKaigi 2019 presentation for live examples.

There are many types of attacks and risks you will encounter when using OSS.

Not all of the risks are connected with malicious activities though.

Risks related to using OSS software

  • Outages
  • Cryptojacking
  • Botnets
  • Data loss
  • Data leakage
  • Legal risks

OSS attack vectors

  • Gems typosquatting
  • Source typosquatting
  • Malicious takeovers
  • Account takeovers
  • Accidental injections
  • Package tampering

Typosquatting

Typosquatting, is a form of cybersquatting which relies on mistakes such as typos made by users when inputting a name.
https://en.wikipedia.org/wiki/Typosquatting

Gems typosquatting

  • sspec -> rspec
  • atlas-client -> atlas_client

and over 700 more

https://rubygems.org/gems/bndler
https://rubygems.org/gems/rials

diff --git a/.ruby-version b/.ruby-version
index ecd7ee5..8e8299d 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.5.8
+2.4.2
diff --git a/damerau-levenshtein.gemspec b/damerau-levenshtein.gemspec
-  s.required_ruby_version = ">= 2.5"
-  s.name = "damerau-levenshtein"
+  s.required_ruby_version = ">= 2.4"
+  s.name = "damerau-levenstein"
-  s.homepage = "https://github.com/GlobalNamesArchitecture/damerau-levenshtein"
+  s.homepage = "https://github.com/DarkWater666/damerau-levenshtein"
-  s.add_development_dependency "activesupport", "~> 6.0"
-  s.add_development_dependency "bundler", "~> 2.1"
-  s.add_development_dependency "byebug", "~> 11.0"
+  s.add_development_dependency "activesupport", "~> 4.2"
+  s.add_development_dependency "bundler", "~> 2.0"

diff --git a/lib/damerau-levenshtein/version.rb b/lib/damerau-levenshtein/version.rb
-  VERSION = "1.3.3"
+  VERSION = "1.3.3.1"
  • Above example is not malicious
  • This type of updates could be used to justify the gem typosquatting existence
  • It could act as a start of a process of building up a reputation
  • Generating malicious gems can be automated really easily
  • RubyGems does prevent from registering the gems with names that are typos of the most popular libraries but that does not always work
  • You can always "book" the names with a non-malicious code just for the future usage

Source typosquatting

http://gavinmiller.io/2020/how-i-mitmd-rubygems-org-kinda/

Similar example but related to bitsquatting can be found in my Taking over a Ruby gem presentation from 2019.

Malicious takeover

That one is probably more problematic as it comes down to social engineering, rather than attacking the ruby gems as a platform.

  • Targeting a single persons lib is not that hard
  • Ruby has a lot of tools that can help with that

By showing an interest

There are:

  • 161 033 gems
  • 1 056 040 versions
  • 5472 gems with over 100 000 downloads
  • 1 996 gems with over 1 000 000 downloads
  • 611 gems with over 10 000 000 downloads
  • 54 gems with over 100 000 000 downloads

Amongst those with more than 100 000 downloads

  • 3 531 weren't updated for at least 1 year
  • 2 617 weren't updated for at least 2 years
  • 1 966 weren't updated for at least 3 years
  • 1 472 weren't updated for at least 4 years
  • 1 045 weren't updated for at least 5 years

Make an effort... effortless

  • Fix invalid permissions in files
  • Detect broken symlinks
  • RuboCop
  • Typos detection
  • Misspellings and additional docs
  • Gem bumps (sic!)
  • Optimizations (via Ducalis, etc)
  • Additional specs
  • Etc...

This is what happened with event-stream

The event-stream module was originally by Dominic Tarr, who maintained the library before handing it to a contributor. Tarr indicated that he has not used the module and transferred its ownership after he received an email regarding its maintenance.

And when you finally get release permissions...

Make it real!

  • I couldn’t find 3.2.0.3 in the GitHub repo
  • I couldn’t find any mention of the version in any issues or changelogs
  • I couldn’t find any mention of the gem being yanked by the owners of the project
https://dgb.github.io/2019/04/05/bootstrap-sass-backdoor.html

Account takeover

Account takeover is a form of identity theft and fraud, where a malicious third party successfully gains access to a user's account credentials.

rest-client 1.6.13

https://my.diffend.io/gems/rest-client/1.6.9/1.6.13/page/1#d2h-017072-851

Account takeover

Luckily for us, this one is going to be tackled in the upcoming weeks.

💪

Accidental injections

This one is funny, because it's... accidental.

Accidental injections


{
  "data/config/access_token.txt.enc": {
    "family": "application",
    "full": "application/x-dosexec"
  }
}

Package tampering

Huge subject on it's own so let's focus on one case:

What if I told you, that what you've uploaded to RubyGems month ago and what is being served right now are two different things?

Package tampering

There is always a possibility, that RubyGems is going to be hacked and that some of the gems content is going to be replaced.

Installing a gem is enough to make things bad.

Possibilities are endless

Because we allow changes in the already installed gems, a malicious code could easily infect other libraries, while cleaning up itself.

It is not a theoretical only problem.

RubyGems as a platform is pretty decent

And now due to 2FA it's even better

RubyGems is getting better :)

I'm in a constant coop with RubyGems core team to provide them with discoveries and to protect all the RubyGems users.

Countermeasures

Yoshitaka Sakurada, the minister for cybersecurity who recently confessed that he does not use computers, has now told a Diet committee that he is not very familiar with cybersecurity issues.

There is no general solution to all the problems

And I feel, that due to dynamic nature of Ruby, there won't be...

Use only verified gems sources


  source 'https://rubуgems.org'
  'у'.bytes => [209, 131]

vs


  source 'https://rubygems.org'
  'y'.bytes => [121]

IDN homograph attack

Watch out for typosquattings

  • sspec -> rspec
  • atlas-client -> atlas_client
  • damerau-levenstein -> damerau-levenshtein

Review licenses of the libraries you use

Unless a license that specifies otherwise is included, nobody else can use, copy, distribute, or modify that library without being at risk of take-downs, shake-downs, or litigation.

Migrate from gems that are abandoned or take them over

Do not use gems that are fairly new

Connect critical CVE notifications to your on-call duty setup

Never install gems without checking them

Bumping policy


rm Gemfile.lock
bundle
bundle exec rspec spec
git add ./
git commit -m "gem bump"
git push origin master

vs


bundle outdated
bundle update XYZ
bundle exec rspec spec
git add ./
git commit -m "gem bump"
git push origin master

Both are bad!

You're not suppose to even install the upgraded libs without carefully reviewing the code.

All the "automatic" dependency management tools that PR updates are really bad by design if you don't have an isolated multi-stage CI flow (for private repos).

Many companies use the same ENV for running specs, building containers, pushing things, etc.


ENV.map { |a, v| [a,v] }.to_s

That's why it's better to always review bumps before installing them.

Reviewing RubyGems code needs to happen based on RubyGems data

Github is not a proper place to do that

RubyGems is

Introducing diffend.io

my.diffend.io

diffend.io

OSS supply chain security and management platform for Ruby applications

that is free :)

diffend.io

Diffend aims to analyze releases packages to find vulnerabilities and quality problems

Plan is to improve the ecosystem of gems releases, the same way we improve our code.

https://diffend.io/docs
ruby <(curl -s https://my.diffend.io/api/setup/ruby)

# or

curl https://my.diffend.io/api/setup/ruby \
  -o /tmp/install.rb; \
ruby /tmp/install.rb

Improving the ecosystem

diffend.io

  • Git leaks
  • Log files
  • Cached assets
  • Executable fonts
  • Executable images
  • License quality
  • Vendor data

You can help!

We're working on building a sandbox with modified MRI to analyze the system behaviour with new gems released.

Summary

  • Trust no one
  • Update only when you're sure of the content
  • Track changes
  • Be aware of your environment
  • Run CI in isolated stages
  • Create a security flow that matches your organization profile
  • Use Diffend 🙏

READ MORE

THE END