VYPR
Moderate severityNVD Advisory· Published Jun 4, 2025· Updated Jun 5, 2025

ReDoS Vulnerability in Rack::Multipart handle_mime_head

CVE-2025-49007

Description

Rack is a modular Ruby web server interface. Starting in version 3.1.0 and prior to version 3.1.16, there is a denial of service vulnerability in the Content-Disposition parsing component of Rack. This is very similar to the previous security issue CVE-2022-44571. Carefully crafted input can cause Content-Disposition header parsing in Rack to take an unexpected amount of time, possibly resulting in a denial of service attack vector. This header is used typically used in multipart parsing. Any applications that parse multipart posts using Rack (virtually all Rails applications) are impacted. Version 3.1.16 contains a patch for the vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
rackRubyGems
>= 3.1.0, < 3.1.163.1.16

Affected products

1

Patches

2
4795831a0a31

Fix ReDoS and consistency in multipart regexes

https://github.com/rack/rackJohn HawthornAug 13, 2024via ghsa
2 files changed · +7 5
  • lib/rack/multipart/parser.rb+5 3 modified
    @@ -31,10 +31,12 @@ class BoundaryTooLongError < StandardError
         Error = BoundaryTooLongError
     
         EOL = "\r\n"
    +    FWS = /[ \t]+(?:\r\n[ \t]+)?/ # whitespace with optional folding
    +    HEADER_VALUE = "(?:[^\r\n]|\r\n[ \t])*" # anything but a non-folding CRLF
         MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|ni
    -    MULTIPART_CONTENT_TYPE = /Content-Type:[ \t]*(.*)#{EOL}/ni
    -    MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:(.*)(?=#{EOL}(\S|\z))/ni
    -    MULTIPART_CONTENT_ID = /Content-ID:[ \t]*([^#{EOL}]*)/ni
    +    MULTIPART_CONTENT_TYPE = /^Content-Type:#{FWS}?(#{HEADER_VALUE})/ni
    +    MULTIPART_CONTENT_DISPOSITION = /^Content-Disposition:#{FWS}?(#{HEADER_VALUE})/ni
    +    MULTIPART_CONTENT_ID = /^Content-ID:#{FWS}?(#{HEADER_VALUE})/ni
     
         class Parser
           BUFSIZE = 1_048_576
    
  • test/spec_multipart.rb+2 2 modified
    @@ -976,7 +976,7 @@ def initialize(*)
         data = <<-EOF
     --AaB03x\r
     content-type: text/plain\r
    -content-disposition: attachment; name="quoted\\\\chars\\"in\rname"\r
    +content-disposition: attachment; name="quoted\\\\chars\\"in\tname"\r
     \r
     true\r
     --AaB03x--\r
    @@ -989,7 +989,7 @@ def initialize(*)
         }
         env = Rack::MockRequest.env_for("/", options)
         params = Rack::Multipart.parse_multipart(env)
    -    params["quoted\\chars\"in\rname"].must_equal 'true'
    +    params["quoted\\chars\"in\tname"].must_equal 'true'
       end
     
       it "supports mixed case metadata" do
    
aed514df37e3

Fix ReDoS and consistency in multipart regexes

https://github.com/rack/rackJohn HawthornAug 13, 2024via ghsa
2 files changed · +8 6
  • lib/rack/multipart/parser.rb+5 3 modified
    @@ -31,10 +31,12 @@ class BoundaryTooLongError < StandardError
         Error = BoundaryTooLongError
     
         EOL = "\r\n"
    +    FWS = /[ \t]+(?:\r\n[ \t]+)?/ # whitespace with optional folding
    +    HEADER_VALUE = "(?:[^\r\n]|\r\n[ \t])*" # anything but a non-folding CRLF
         MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|ni
    -    MULTIPART_CONTENT_TYPE = /Content-Type: (.*)#{EOL}/ni
    -    MULTIPART_CONTENT_DISPOSITION = /Content-Disposition:(.*)(?=#{EOL}(\S|\z))/ni
    -    MULTIPART_CONTENT_ID = /Content-ID:\s*([^#{EOL}]*)/ni
    +    MULTIPART_CONTENT_TYPE = /^Content-Type:#{FWS}?(#{HEADER_VALUE})/ni
    +    MULTIPART_CONTENT_DISPOSITION = /^Content-Disposition:#{FWS}?(#{HEADER_VALUE})/ni
    +    MULTIPART_CONTENT_ID = /^Content-ID:#{FWS}?(#{HEADER_VALUE})/ni
     
         class Parser
           BUFSIZE = 1_048_576
    
  • test/spec_multipart.rb+3 3 modified
    @@ -334,7 +334,7 @@ def rd.rewind; end
     
       it "ignores content-disposition values over to 1536 bytes" do
         x = content_disposition_parse.call("a=#{'a'*1510}; filename=\"bar\"; name=\"file\"")
    -    x.must_equal "text/plain"=>[""]
    +    x.must_equal "application/pdf"=>[""]
       end
     
       it 'raises an EOF error on content-length mismatch' do
    @@ -955,7 +955,7 @@ def initialize(*)
         data = <<-EOF
     --AaB03x\r
     content-type: text/plain\r
    -content-disposition: attachment; name="quoted\\\\chars\\"in\rname"\r
    +content-disposition: attachment; name="quoted\\\\chars\\"in\tname"\r
     \r
     true\r
     --AaB03x--\r
    @@ -968,7 +968,7 @@ def initialize(*)
         }
         env = Rack::MockRequest.env_for("/", options)
         params = Rack::Multipart.parse_multipart(env)
    -    params["quoted\\chars\"in\rname"].must_equal 'true'
    +    params["quoted\\chars\"in\tname"].must_equal 'true'
       end
     
       it "supports mixed case metadata" do
    

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

6

News mentions

0

No linked articles in our index yet.