RubyGems on the watch

$ whoami

Maciej Mensfeld

  • Creator of Mend Supply Chain Defender
  • Principal Architect at Mend
  • RubyGems Security Team member
  • OSS contributor (~16 years with Ruby)
  • Karafka creator (Ruby + Kafka)

today@rubygems.org

today@rubygems.org

  • YES rubygems.org is NOT malicious,
  • YES we know what Google/Chrome says
  • YES we reported that
  • NO, we cannot do more than that and we're waiting for Google to fix this

today@rubygems.org

  • RubyGems API may be affected
  • metasploit-payloads is NOT malicious

Agenda

  • OSS Supply Chain
  • Recent RubyGems Critical Incidents
  • Countermeasures & mitigation

What do I hope to leave you with

RubyGems security team does many things to make sure things operate as expected.

In many ways we lead the way.

OSS Security in the end is your responsibility.

Disclaimers

I'm just a small part of the RubyGems team
Today's presentation is mostly about my work for the RubyGems ecosystem

OSS Supply Chain

How OSS distribution works

How OSS distribution works (complex case)

RubyGems is the primary package registry for the Ruby community.

  • Over 176k active packages
  • 132 billion downloads
  • 1 release every 3 minutes
  • Over 433 mln lines of content monthly (162 lines per second)
  • Over 7.5 mln lines of changes monthly

https://asciinema.org/a/0AXXCMVA5lOSeOzJDBEI0ZOlR?speed=0.2&t=5

60%-80% of an average app’s code base is comprised of open source

OSS attacks origins

  • Internal (made by legit owners of packages)
  • External (made by malicious actors)

OSS attacks targets

  • Platform (exploits, bugs, edge-cases)
  • Gems/Users (packages)

Recent RubyGems Critical Incidents

Platform exploitation

Severity: Critical

Unauthorized Package Takeover

CVE-2022-29176

CVE-2022-29176


          find_by!(full_name: "#{rubygem.name}-#{slug}")
          

A bug in RubyGems that allowed unauthorized actors to yank (remove) a package version without being its owner.

CVE-2022-29176

By removing all the versions, under certain circumstances the name could be available for a reuse. This means that we’ve got ourselves a great new package name available for use.

CVE-2022-29176

Packages immutability

CVE-2022-29176

Packages immutability

What is often missed here is that a single RubyGems version is unique only within the scope of the platform on which it was released

CVE-2022-29176

Lockfile to the rescue

CVE-2022-29176

Impact assessment

CVE-2022-29176

Impact assessment

CVE-2022-29176

Impact assessment


SELECT versions.package_id from versions
  inner join (
    SELECT "versions"."package_id", "versions"."number"
    FROM "versions" WHERE  yanked_at is not null
  ) yanked
  on versions.package_id = yanked.package_id
  AND versions.number = yanked.number
  where versions.yanked_at is null
CVE-2022-29176

Impact assessment

Platform exploitation

Protecting against unknown

To stay one step ahead of attackers, we need to focus on what they want to achieve, not how they want to do it.

Platform exploitation

End goal: packages infection

  • Packages tampering
  • Packages highjacking (ATOs)

Platform exploitation

Packages tampering

Platform exploitation

Severity: Critical

Unauthorized Takeover of New Gem Versions via Cache Poisoning

CVE-2022-29218

CVE-2022-29218

Impact assessment

  • Incomplete data structure validation within the metadata file that is being used to read gem data upon version release to trigger an error
  • Ordering mistake in the code that accepts gem uploads that would store the package version despite the release process being halted with an exception
CVE-2022-29218

Impact assessment

Using the two issues together allowed the attacker to save “not yet released” versions in the RubyGems S3 bucket.

CVE-2022-29218

Impact assessment

CVE-2022-29218

Impact assessment

CVE-2022-29218

Impact assessment

CVE-2022-29218

Impact assessment

What about package versions immutability?

CVE-2022-29218

Impact assessment

What about Bundler checksum verification?

CVE-2022-29218

Impact assessment


bundle add bundler-integrity
# And run this to verify integrity of your local installation
bundle exec bundler-integrity
# Export to correlate in scale
bundle exec bundler-integrity export
          

Brandjacking

Brandjacking is an activity whereby someone acquires or otherwise assumes the online identity of another entity for the purposes of acquiring that person's or business's brand equity.

Brandjacking

The idea is to leverage inconsistent naming, particularly by big brands with many packages, and users assumptions about naming conventions or to "provide" SKDs for platforms that do not provide them on their own.

Brandjacking

github.com/googleapis/google-api-ruby-client

does not mean, that the package will be named

google-api-ruby-client

Brandjacking

github.com/aws/aws-sdk-ruby

does not mean, that the package will be named

aws-sdk-ruby

Brandjacking

github.com/azure/azure-sdk-for-js

does not mean, that the package will be named

azure-sdk-for-js

Brandjacking

RubyGems provides APIs and data that you can query to get relevant informations about packages.

With that, you can easily generate list of popular packages that have a mismatch in between their Github/Gitlab name and their registry name.

Brandjacking

But there's more!

Even the way RubyGems builds new packages can help malicious actors!

Brandjacking


Install the gem and add to the application's Gemfile by executing:

    $ bundle add <%= config[:name] %>

If bundler is not being used to manage dependencies, install the gem by executing:

    $ gem install <%= config[:name] %>
          

Brandjacking

The risk is real

There are weeks with several packages that we have to remove.

Expired domains monitoring

  • People make mistakes
  • Their domains expire
  • But their RubyGems account don't!

Expired domains monitoring

RubyGems automatically locks domains close to expiration to prevent their malicious takeover.

Open Source is a “great” way into a company’s software supply chain

Essentially no company has the time to read every line of code in every package and update they use

Understanding the risks

Your software supply chain risks are inherited from your dependencies

Risks related to using OSS software

Getting access to production enviroment is not always the goal of the attacker.

Underestimating OSS supply risks puts at risk your customers as well


          req.write(
            Buffer.from(JSON.stringify(process.env)).toString('base64')
          );
          

Installing packages is enough to make things bad for many of the ecosystems.

Possibilities are endless

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

There are 162 lines of changes released to RubyGems every second.

There are 6 lines of additions released to RubyGems every second.

Summary

  • Trust no one
  • Watch out for RubyGems announcements / CVEs
  • Update only when you're sure of the content
  • Track changes
  • Run CI in isolated stages
  • Take care of your whole SDLC
  • Use Mend 🙏

Thank you

For more details, find me/us on Twitter:

  • @maciejmensfeld
  • @mend_io