diff options
author | Samuel Giddins <[email protected]> | 2024-04-11 00:05:42 -0700 |
---|---|---|
committer | git <[email protected]> | 2024-04-30 15:34:48 +0000 |
commit | d950609ec709c7c4dc48603b9b2d88f840a520fb () | |
tree | 2da7c1649e163787a16d702e419f1d2b3df785c4 /lib/rubygems/package.rb | |
parent | e0949c3f7cbf32d46ee276d69343b7cb8da4325f (diff) |
[rubygems/rubygems] Add a limit to the size of the metadata and checksums files in a gem package.
This is to prevent a malicious gem from causing a denial of service by including a very large metadata or checksums file, which is then read into memory in its entirety just by opening the gem package. This is guaranteed to limit the amount of memory needed, since gzips (which use deflate streams for compression) have a maximum compression ratio of 1032:1, so the uncompressed size of the metadata or checksums file will be at most 1032 times the size of the (limited) amount of data read. This prevents a gem from causing 500GB of memory to be allocated to read a 500MB metadata file. https://.com/rubygems/rubygems/commit/a596e3c5ec
-rw-r--r-- | lib/rubygems/package.rb | 17 |
1 files changed, 12 insertions, 5 deletions
@@ -527,12 +527,13 @@ EOM # Loads a Gem::Specification from the TarEntry +entry+ def load_spec(entry) # :nodoc: case entry.full_name when "metadata" then - @spec = Gem::Specification.from_yaml entry.read when "metadata.gz" then Zlib::GzipReader.wrap(entry, external_encoding: Encoding::UTF_8) do |gzio| - @spec = Gem::Specification.from_yaml gzio.read end end end @@ -556,7 +557,7 @@ EOM @checksums = gem.seek "checksums.yaml.gz" do |entry| Zlib::GzipReader.wrap entry do |gz_io| - Gem::SafeYAML.safe_load gz_io.read end end end @@ -663,7 +664,7 @@ EOM case file_name when /\.sig$/ then - @signatures[$`] = entry.read if @security_policy return else digest entry @@ -714,7 +715,7 @@ EOM raise Gem::Package::FormatError.new(e.message, entry.full_name) end - if RUBY_ENGINE == "truffleruby" def copy_stream(src, dst) # :nodoc: dst.write src.read end @@ -723,6 +724,12 @@ EOM IO.copy_stream(src, dst) end end end require_relative "package/digest_io" |