VYPR
Moderate severityNVD Advisory· Published Mar 1, 2013· Updated Apr 29, 2026

CVE-2013-0183

CVE-2013-0183

Description

multipart/parser.rb in Rack 1.3.x before 1.3.8 and 1.4.x before 1.4.3 allows remote attackers to cause a denial of service (memory consumption and out-of-memory error) via a long string in a Multipart HTTP packet.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
rackRubyGems
>= 1.3.0, < 1.3.81.3.8
rackRubyGems
>= 1.4.0, < 1.4.31.4.3

Affected products

11
  • Rack Project/Rack11 versions
    cpe:2.3:a:rack_project:rack:1.3.0:*:*:*:*:*:*:*+ 10 more
    • cpe:2.3:a:rack_project:rack:1.3.0:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.3.1:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.3.2:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.3.3:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.3.4:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.3.5:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.3.6:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.3.7:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.4.0:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.4.1:*:*:*:*:*:*:*
    • cpe:2.3:a:rack_project:rack:1.4.2:*:*:*:*:*:*:*

Patches

2
f95113402b72

multipart/parser: avoid unbounded #gets method

https://github.com/rack/rackEric WongAug 22, 2012via ghsa
2 files changed · +63 3
  • lib/rack/multipart/parser.rb+10 3 modified
    @@ -70,9 +70,16 @@ def rx
     
           def fast_forward_to_first_boundary
             loop do
    -          read_buffer = @io.gets
    -          break if read_buffer == full_boundary
    -          raise EOFError, "bad content body" if read_buffer.nil?
    +          content = @io.read(BUFSIZE)
    +          raise EOFError, "bad content body" unless content
    +          @buf << content
    +
    +          while @buf.gsub!(/\A([^\n]*\n)/, '')
    +            read_buffer = $1
    +            return if read_buffer == full_boundary
    +          end
    +
    +          raise EOFError, "bad content body" if Utils.bytesize(@buf) >= BUFSIZE
             end
           end
     
    
  • test/spec_multipart.rb+53 0 modified
    @@ -48,6 +48,59 @@ def multipart_file(name)
         params['profile']['bio'].should.include 'hello'
       end
     
    +  should "reject insanely long boundaries" do
    +    # using a pipe since a tempfile can use up too much space
    +    rd, wr = IO.pipe
    +
    +    # we only call rewind once at start, so make sure it succeeds
    +    # and doesn't hit ESPIPE
    +    def rd.rewind; end
    +    wr.sync = true
    +
    +    # mock out length to make this pipe look like a Tempfile
    +    def rd.length
    +      1024 * 1024 * 8
    +    end
    +
    +    # write to a pipe in a background thread, this will write a lot
    +    # unless Rack (properly) shuts down the read end
    +    thr = Thread.new do
    +      begin
    +        wr.write("--AaB03x")
    +
    +        # make the initial boundary a few gigs long
    +        longer = "0123456789" * 1024 * 1024
    +        (1024 * 1024).times { wr.write(longer) }
    +
    +        wr.write("\r\n")
    +        wr.write('Content-Disposition: form-data; name="a"; filename="a.txt"')
    +        wr.write("\r\n")
    +        wr.write("Content-Type: text/plain\r\n")
    +        wr.write("\r\na")
    +        wr.write("--AaB03x--\r\n")
    +        wr.close
    +      rescue => err # this is EPIPE if Rack shuts us down
    +        err
    +      end
    +    end
    +
    +    fixture = {
    +      "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
    +      "CONTENT_LENGTH" => rd.length.to_s,
    +      :input => rd,
    +    }
    +
    +    env = Rack::MockRequest.env_for '/', fixture
    +    lambda {
    +      Rack::Multipart.parse_multipart(env)
    +    }.should.raise(EOFError)
    +    rd.close
    +
    +    err = thr.value
    +    err.should.be.instance_of Errno::EPIPE
    +    wr.close
    +  end
    +
       should "parse multipart upload with text file" do
         env = Rack::MockRequest.env_for("/", multipart_fixture(:text))
         params = Rack::Multipart.parse_multipart(env)
    
548b9af2dc00

multipart/parser: avoid unbounded #gets method

https://github.com/rack/rackEric WongAug 22, 2012via ghsa
2 files changed · +63 3
  • lib/rack/multipart/parser.rb+10 3 modified
    @@ -78,9 +78,16 @@ def rx
     
           def fast_forward_to_first_boundary
             loop do
    -          read_buffer = @io.gets
    -          break if read_buffer == full_boundary
    -          raise EOFError, "bad content body" if read_buffer.nil?
    +          content = @io.read(BUFSIZE)
    +          raise EOFError, "bad content body" unless content
    +          @buf << content
    +
    +          while @buf.gsub!(/\A([^\n]*\n)/, '')
    +            read_buffer = $1
    +            return if read_buffer == full_boundary
    +          end
    +
    +          raise EOFError, "bad content body" if Utils.bytesize(@buf) >= BUFSIZE
             end
           end
     
    
  • test/spec_multipart.rb+53 0 modified
    @@ -48,6 +48,59 @@ def multipart_file(name)
         params['profile']['bio'].should.include 'hello'
       end
     
    +  should "reject insanely long boundaries" do
    +    # using a pipe since a tempfile can use up too much space
    +    rd, wr = IO.pipe
    +
    +    # we only call rewind once at start, so make sure it succeeds
    +    # and doesn't hit ESPIPE
    +    def rd.rewind; end
    +    wr.sync = true
    +
    +    # mock out length to make this pipe look like a Tempfile
    +    def rd.length
    +      1024 * 1024 * 8
    +    end
    +
    +    # write to a pipe in a background thread, this will write a lot
    +    # unless Rack (properly) shuts down the read end
    +    thr = Thread.new do
    +      begin
    +        wr.write("--AaB03x")
    +
    +        # make the initial boundary a few gigs long
    +        longer = "0123456789" * 1024 * 1024
    +        (1024 * 1024).times { wr.write(longer) }
    +
    +        wr.write("\r\n")
    +        wr.write('Content-Disposition: form-data; name="a"; filename="a.txt"')
    +        wr.write("\r\n")
    +        wr.write("Content-Type: text/plain\r\n")
    +        wr.write("\r\na")
    +        wr.write("--AaB03x--\r\n")
    +        wr.close
    +      rescue => err # this is EPIPE if Rack shuts us down
    +        err
    +      end
    +    end
    +
    +    fixture = {
    +      "CONTENT_TYPE" => "multipart/form-data; boundary=AaB03x",
    +      "CONTENT_LENGTH" => rd.length.to_s,
    +      :input => rd,
    +    }
    +
    +    env = Rack::MockRequest.env_for '/', fixture
    +    lambda {
    +      Rack::Multipart.parse_multipart(env)
    +    }.should.raise(EOFError)
    +    rd.close
    +
    +    err = thr.value
    +    err.should.be.instance_of Errno::EPIPE
    +    wr.close
    +  end
    +
       should "parse multipart upload with text file" do
         env = Rack::MockRequest.env_for("/", multipart_fixture(:text))
         params = Rack::Multipart.parse_multipart(env)
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

18

News mentions

0

No linked articles in our index yet.