python.django.security.injection.request-data-fileresponse.request-data-fileresponse

Community Favorite
profile photo of semgrepsemgrep
Author
12,102
Download Count*

Found user-controlled request data being passed into a file open, which is them passed as an argument into the FileResponse. This is dangerous because an attacker could specify an arbitrary file to read, which could result in leaking important data. Be sure to validate or sanitize the user-inputted filename in the request data before using it in FileResponse.

Run Locally

Run in CI

Defintion

rules:
  - id: request-data-fileresponse
    message: Found user-controlled request data being passed into a file open, which
      is them passed as an argument into the FileResponse. This is dangerous
      because an attacker could specify an arbitrary file to read, which could
      result in leaking important data. Be sure to validate or sanitize the
      user-inputted filename in the request data before using it in
      FileResponse.
    metadata:
      cwe:
        - "CWE-22: Improper Limitation of a Pathname to a Restricted Directory
          ('Path Traversal')"
      owasp:
        - A05:2017 - Broken Access Control
        - A01:2021 - Broken Access Control
      references:
        - https://django-book.readthedocs.io/en/latest/chapter20.html#cross-site-scripting-xss
      category: security
      technology:
        - django
      cwe2022-top25: true
      cwe2021-top25: true
      subcategory:
        - vuln
      likelihood: LOW
      impact: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Path Traversal
    languages:
      - python
    severity: WARNING
    patterns:
      - pattern-inside: |
          def $FUNC(...):
            ...
      - pattern-either:
          - pattern: django.http.FileResponse(..., request.$W.get(...), ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              django.http.FileResponse(..., open($DATA, ...), ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              $INTERM = open($DATA, ...)
              ...
              django.http.FileResponse(..., $INTERM, ...)
          - pattern: $A = django.http.FileResponse(..., request.$W.get(...), ...)
          - pattern: return django.http.FileResponse(..., request.$W.get(...), ...)
          - pattern: django.http.FileResponse(..., request.$W(...), ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              django.http.FileResponse(..., open($DATA, ...), ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              $INTERM = open($DATA, ...)
              ...
              django.http.FileResponse(..., $INTERM, ...)
          - pattern: $A = django.http.FileResponse(..., request.$W(...), ...)
          - pattern: return django.http.FileResponse(..., request.$W(...), ...)
          - pattern: django.http.FileResponse(..., request.$W[...], ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              django.http.FileResponse(..., open($DATA, ...), ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              $INTERM = open($DATA, ...)
              ...
              django.http.FileResponse(..., $INTERM, ...)
          - pattern: $A = django.http.FileResponse(..., request.$W[...], ...)
          - pattern: return django.http.FileResponse(..., request.$W[...], ...)
          - pattern: django.http.FileResponse(..., request.$W, ...)
          - pattern: |
              $DATA = request.$W
              ...
              django.http.FileResponse(..., open($DATA, ...), ...)
          - pattern: |
              $DATA = request.$W
              ...
              $INTERM = open($DATA, ...)
              ...
              django.http.FileResponse(..., $INTERM, ...)
          - pattern: $A = django.http.FileResponse(..., request.$W, ...)
          - pattern: return django.http.FileResponse(..., request.$W, ...)

Examples

request-data-fileresponse.py

from django.http import FileResponse

def func(request):
    # ruleid: request-data-fileresponse
    filename = request.POST.get("filename")
    f = open(filename, 'rb')
    return FileResponse(f)

def safe(request):
    # ok: request-data-fileresponse
    url = request.GET.get("url")
    print(url)
    f = open("blah.txt", 'r')
    return FileResponse(f)