ruby.rails.security.brakeman.check-send-file.check-send-file

profile photo of semgrepsemgrep
Author
unknown
Download Count*

Allowing user input to send_file allows a malicious user to potentially read arbitrary files from the server. Avoid accepting user input in send_file or normalize with File.basename(...)

Run Locally

Run in CI

Defintion

rules:
  - id: check-send-file
    mode: taint
    pattern-sources:
      - pattern-either:
          - pattern: |
              cookies[...]
          - patterns:
              - pattern: |
                  cookies. ... .$PROPERTY[...]
              - metavariable-regex:
                  metavariable: $PROPERTY
                  regex: (?!signed|encrypted)
          - pattern: |
              params[...]
          - pattern: |
              request.env[...]
    pattern-sinks:
      - patterns:
          - pattern: |
              send_file ...
    message: Allowing user input to `send_file` allows a malicious user to
      potentially read arbitrary files from the server. Avoid accepting user
      input in `send_file` or normalize with `File.basename(...)`
    languages:
      - ruby
    severity: ERROR
    metadata:
      source-rule-url: https://github.com/presidentbeef/brakeman/blob/main/lib/brakeman/checks/check_send_file.rb
      category: security
      cwe:
        - "CWE-73: External Control of File Name or Path"
      owasp:
        - A04:2021 - Insecure Design
      technology:
        - ruby
        - rails
      references:
        - https://owasp.org/www-community/attacks/Path_Traversal
        - https://owasp.org/Top10/A01_2021-Broken_Access_Control/
      subcategory:
        - vuln
      likelihood: MEDIUM
      impact: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Path Traversal

Examples

check-send-file.rb

def test_send_file
    # ruleid: check-send-file
    send_file params[:file]
end

def test_send_file2
    # ruleid: check-send-file
    send_file cookies[:something]
end

def test_send_file3
    # ruleid: check-send-file
    send_file cookies.permanent[:something]
end

def test_send_file4
    # ruleid: check-send-file
    send_file cookies.permanent[:something]
end

def test_send_file5
    # ok: check-send-file
    send_file cookies.encrypted[:something]
end

def test_send_file6
    # this is reported since semgrep 0.94 because . ... . can now match
    # intermediate fields, not just method calls.
    # ruleid: check-send-file
    send_file cookies.signed.permanent[:something]
end

def test_send_file7
    # ok: check-send-file
    send_file cookies.permanent.signed[:something]
end

def test_send_file8
    # ruleid: check-send-file
    send_file request.env[:badheader]
end

def test_send_file_ok
    # ok: check-send-file
    send_file "some_safe_file.txt"
end