|
| 1 | +--- |
| 2 | +title: RubyGems & xz |
| 3 | +layout: post |
| 4 | +author: Samuel Giddins |
| 5 | +author_email: segiddins@segiddins.me |
| 6 | +--- |
| 7 | + |
| 8 | +The past few days have seen the security world focused on the revelation of the [xy/liblzma backdoor](https://xeiaso.net/notes/2024/xz-vuln/), which has been assigned [CVE-2024-3094](https://nvd.nist.gov/vuln/detail/CVE-2024-3094). |
| 9 | + |
| 10 | +In response to this, I have undertaken an exposure assesment of the vulnerability on RubyGems.org and the broader RubyGems ecosystem. |
| 11 | +I am happy to report that RubyGems.org is not vulnerable to this issue, as we use a `musl` based operating system (Alpine) for our RubyGems.org containers. |
| 12 | + |
| 13 | +Furthermore, I am happy to confirm that there is no evidence that gems in the RubyGems ecosystem have been used an attack vector for this vulnerability. |
| 14 | +Thanks to the data consolidated in the [rubygems-research](https://github.com/segiddins/rubygems-research) project (available publicly at [research.rubygems.info](https://research.rubygems.info)), we can confirm that no gems contain any references to the vulnerable `liblzma` library. |
| 15 | + |
| 16 | +I would like to thank the rest of the RubyGems.org security team for their support in this investigation, and for their continued dedication to the security of the ecosystem. I would also like to thank AWS for their continued support of RubyGems security, sponsoring myself as [Ruby Central's security engineer in residence](https://rubycentral.org/news/ruby-central-welcomes-new-software-engineer-in-residence-sponsored-by-aws/), and funding the development of the [rubygems-research](https://github.com/segiddins/rubygems-research) project, which proved instrumental in confirming the absence of `liblzma` across all million and a half gem versions hosted on RubyGems.org. |
| 17 | + |
| 18 | +## Nitty Gritty Details |
| 19 | + |
| 20 | +RubyGems.org app containers do not contain any vulnerable versions of `liblzma` nor `xz` (in addition to the fact that they run Alpine and thus were not vulnerable to the backdoor). |
| 21 | + |
| 22 | +``` |
| 23 | +web-7b88594bd9-6g5nn:/app find / -name '*lzma*' |
| 24 | +/usr/bin/lzma |
| 25 | +/usr/bin/unlzma |
| 26 | +/usr/lib/liblzma.so.5 |
| 27 | +/usr/lib/liblzma.so.5.4.3 |
| 28 | +/app/vendor/ruby/3.3.0/gems/bindata-2.5.0/lib/bindata/transform/lzma.rb |
| 29 | +``` |
| 30 | + |
| 31 | +``` |
| 32 | +web-7b88594bd9-6g5nn:/app# find / -name '*xz*' |
| 33 | +/sys/module/xz_dec |
| 34 | +/usr/bin/unxz |
| 35 | +/usr/bin/xzcat |
| 36 | +/app/vendor/ruby/3.3.0/gems/bindata-2.5.0/lib/bindata/transform/xz.rb |
| 37 | +``` |
| 38 | + |
| 39 | +No ecosystem gems contain a vulnerable `liblzma.so`. |
| 40 | + |
| 41 | +```irb |
| 42 | +irb(main):005> attrs = ['version_data_entries.full_name', 'rubygems.name', 'versions.number', 'versions.platform', 'versions.uploaded_at'] |
| 43 | +=> ["version_data_entries.full_name", "rubygems.name", "versions.number", "versions.platform", "versions.uploaded_at"] |
| 44 | +irb(main):006> VersionDataEntry.where('version_data_entries.name LIKE ?', 'liblzma%.so').joins(:version, :rubygem).pluck(*attrs).map { |p| attrs.zip(p).to_h } |
| 45 | +=> |
| 46 | +[{"version_data_entries.full_name"=>"lib/liblzma.so", "rubygems.name"=>"liblzma", "versions.number"=>"0.2", "versions.platform"=>"mingw32", "versions.uploaded_at"=>Sat, 31 Mar 2012 05:57:47.212691000 UTC +00:00}, |
| 47 | + {"version_data_entries.full_name"=>"lib/1.9.1/liblzma.so", |
| 48 | + "rubygems.name"=>"liblzma", |
| 49 | + "versions.number"=>"0.3", |
| 50 | + "versions.platform"=>"x86-mingw32", |
| 51 | + "versions.uploaded_at"=>Thu, 21 Feb 2013 13:21:51.961608000 UTC +00:00}, |
| 52 | + {"version_data_entries.full_name"=>"lib/2.0.0/liblzma.so", |
| 53 | + "rubygems.name"=>"liblzma", |
| 54 | + "versions.number"=>"0.3", |
| 55 | + "versions.platform"=>"x86-mingw32", |
| 56 | + "versions.uploaded_at"=>Thu, 21 Feb 2013 13:21:51.961608000 UTC +00:00}] |
| 57 | +``` |
| 58 | + |
| 59 | +```irb |
| 60 | +irb(main):008> VersionDataEntry.where('version_data_entries.name = ?', 'xz').joins(:version, :rubygem).pluck(*attrs).map { |p| attrs.zip(p).to_h } |
| 61 | +=> [] |
| 62 | +``` |
0 commit comments