VYPR
High severityNVD Advisory· Published Nov 28, 2022· Updated Nov 4, 2025

Sinatra vulnerable to Reflected File Download attack

CVE-2022-45442

Description

Sinatra is a domain-specific language for creating web applications in Ruby. An issue was discovered in Sinatra 2.0 before 2.2.3 and 3.0 before 3.0.4. An application is vulnerable to a reflected file download (RFD) attack that sets the Content-Disposition header of a response when the filename is derived from user-supplied input. Version 2.2.3 and 3.0.4 contain patches for this issue.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Sinatra versions before 2.2.3 and 3.0.4 are vulnerable to reflected file download (RFD) attacks via user-supplied filenames in the Content-Disposition header.

Vulnerability

Sinatra, a Ruby web application DSL, is vulnerable to a reflected file download (RFD) attack in versions 2.0 before 2.2.3 and 3.0 before 3.0.4. The issue arises when the Content-Disposition header of a response is set with a filename derived from user-supplied input without proper sanitization. This allows an attacker to control the filename and extension of a downloaded file [1][2].

Exploitation

An attacker can exploit this by crafting a malicious link or form submission that triggers a response where the Content-Disposition header includes a filename such as malicious.bat or malicious.exe. When the victim clicks the link, the browser downloads the file with the attacker-controlled extension. The attack requires user interaction (e.g., clicking a link) and does not require authentication, as it can be triggered from any page that interacts with the vulnerable Sinatra application [2][3].

Impact

Successful exploitation could lead to arbitrary code execution on the victim's system if the downloaded file is opened. For example, a .bat file on Windows could execute commands, or a .jar file could run Java code. The impact is limited by the user's action of opening the file, but it can lead to full compromise of the client machine [2][3].

Mitigation

Sinatra has addressed this vulnerability in versions 2.2.3 and 3.0.4. Users should upgrade to these patched versions or later. No workaround is available; updating the gem is the recommended action [1][2][3].

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
sinatraRubyGems
>= 3.0, < 3.0.43.0.4
sinatraRubyGems
>= 2.0.0, < 2.2.32.2.3

Affected products

4

Patches

1
ea8fc9495a35

escape filename in the Content-Disposition header

https://github.com/sinatra/sinatranamusyakaNov 23, 2022via ghsa
2 files changed · +20 1
  • lib/sinatra/base.rb+8 1 modified
    @@ -396,13 +396,20 @@ def content_type(type = nil, params = {})
           response['Content-Type'] = mime_type
         end
     
    +    # https://html.spec.whatwg.org/#multipart-form-data
    +    MULTIPART_FORM_DATA_REPLACEMENT_TABLE = {
    +      '"'  => '%22',
    +      "\r" => '%0D',
    +      "\n" => '%0A'
    +    }.freeze
    +
         # Set the Content-Disposition to "attachment" with the specified filename,
         # instructing the user agents to prompt to save.
         def attachment(filename = nil, disposition = :attachment)
           response['Content-Disposition'] = disposition.to_s.dup
           return unless filename
     
    -      params = format('; filename="%s"', File.basename(filename))
    +      params = format('; filename="%s"', File.basename(filename).gsub(/["\r\n]/, MULTIPART_FORM_DATA_REPLACEMENT_TABLE))
           response['Content-Disposition'] << params
           ext = File.extname(filename)
           content_type(ext) unless response['Content-Type'] || ext.empty?
    
  • test/helpers_test.rb+12 0 modified
    @@ -781,6 +781,18 @@ def attachment_app(filename=nil)
           assert_equal '<sinatra></sinatra>', body
         end
     
    +    it 'escapes filename in the Content-Disposition header according to the multipart form data spec in WHATWG living standard' do
    +      mock_app do
    +        get('/attachment') do
    +          attachment "test.xml\";\r\next=.txt"
    +          response.write("<sinatra></sinatra>")
    +        end
    +      end
    +
    +      get '/attachment'
    +      assert_equal 'attachment; filename="test.xml%22;%0D%0Aext=.txt"', response['Content-Disposition']
    +      assert_equal '<sinatra></sinatra>', body
    +    end
       end
     
       describe 'send_file' do
    

Vulnerability mechanics

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

References

9

News mentions

0

No linked articles in our index yet.