python.django.security.injection.reflected-data-httpresponse.reflected-data-httpresponse

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

Found user-controlled request data passed into HttpResponse. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed.

Run Locally

Run in CI

Defintion

rules:
  - id: reflected-data-httpresponse
    message: Found user-controlled request data passed into HttpResponse. This could
      be vulnerable to XSS, leading to attackers gaining access to user cookies
      and protected information. Ensure that the request data is properly
      escaped or sanitzed.
    metadata:
      cwe:
        - "CWE-79: Improper Neutralization of Input During Web Page Generation
          ('Cross-site Scripting')"
      owasp:
        - A07:2017 - Cross-Site Scripting (XSS)
        - A03:2021 - Injection
      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: MEDIUM
      impact: MEDIUM
      confidence: MEDIUM
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
      vulnerability_class:
        - Cross-Site-Scripting (XSS)
    languages:
      - python
    severity: WARNING
    patterns:
      - pattern-inside: |
          def $FUNC(...):
            ...
      - pattern-either:
          - pattern: django.http.HttpResponse(..., $S.format(..., request.$W.get(...), ...),
              ...)
          - pattern: django.http.HttpResponse(..., $S % request.$W.get(...), ...)
          - pattern: django.http.HttpResponse(..., f"...{request.$W.get(...)}...", ...)
          - pattern: django.http.HttpResponse(..., request.$W.get(...), ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              django.http.HttpResponse(..., $DATA, ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              $INTERM = $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              $INTERM = $STR.format(..., $DATA, ...)
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              django.http.HttpResponse(..., $STR % $DATA, ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              $INTERM = $STR % $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              django.http.HttpResponse(..., f"...{$DATA}...", ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              $INTERM = f"...{$DATA}..."
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              django.http.HttpResponse(..., $STR + $DATA, ...)
          - pattern: |
              $DATA = request.$W.get(...)
              ...
              $INTERM = $STR + $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: $A = django.http.HttpResponse(..., request.$W.get(...), ...)
          - pattern: return django.http.HttpResponse(..., request.$W.get(...), ...)
          - pattern: django.http.HttpResponse(..., $S.format(..., request.$W(...), ...),
              ...)
          - pattern: django.http.HttpResponse(..., $S % request.$W(...), ...)
          - pattern: django.http.HttpResponse(..., f"...{request.$W(...)}...", ...)
          - pattern: django.http.HttpResponse(..., request.$W(...), ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              django.http.HttpResponse(..., $DATA, ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              $INTERM = $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              $INTERM = $STR.format(..., $DATA, ...)
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              django.http.HttpResponse(..., $STR % $DATA, ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              $INTERM = $STR % $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              django.http.HttpResponse(..., f"...{$DATA}...", ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              $INTERM = f"...{$DATA}..."
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              django.http.HttpResponse(..., $STR + $DATA, ...)
          - pattern: |
              $DATA = request.$W(...)
              ...
              $INTERM = $STR + $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: $A = django.http.HttpResponse(..., request.$W(...), ...)
          - pattern: return django.http.HttpResponse(..., request.$W(...), ...)
          - pattern: django.http.HttpResponse(..., $S.format(..., request.$W[...], ...),
              ...)
          - pattern: django.http.HttpResponse(..., $S % request.$W[...], ...)
          - pattern: django.http.HttpResponse(..., f"...{request.$W[...]}...", ...)
          - pattern: django.http.HttpResponse(..., request.$W[...], ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              django.http.HttpResponse(..., $DATA, ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              $INTERM = $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              $INTERM = $STR.format(..., $DATA, ...)
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              django.http.HttpResponse(..., $STR % $DATA, ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              $INTERM = $STR % $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              django.http.HttpResponse(..., f"...{$DATA}...", ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              $INTERM = f"...{$DATA}..."
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              django.http.HttpResponse(..., $STR + $DATA, ...)
          - pattern: |
              $DATA = request.$W[...]
              ...
              $INTERM = $STR + $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: $A = django.http.HttpResponse(..., request.$W[...], ...)
          - pattern: return django.http.HttpResponse(..., request.$W[...], ...)
          - pattern: django.http.HttpResponse(..., $S.format(..., request.$W, ...), ...)
          - pattern: django.http.HttpResponse(..., $S % request.$W, ...)
          - pattern: django.http.HttpResponse(..., f"...{request.$W}...", ...)
          - pattern: django.http.HttpResponse(..., request.$W, ...)
          - pattern: |
              $DATA = request.$W
              ...
              django.http.HttpResponse(..., $DATA, ...)
          - pattern: |
              $DATA = request.$W
              ...
              $INTERM = $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W
              ...
              django.http.HttpResponse(..., $STR.format(..., $DATA, ...), ...)
          - pattern: |
              $DATA = request.$W
              ...
              $INTERM = $STR.format(..., $DATA, ...)
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W
              ...
              django.http.HttpResponse(..., $STR % $DATA, ...)
          - pattern: |
              $DATA = request.$W
              ...
              $INTERM = $STR % $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W
              ...
              django.http.HttpResponse(..., f"...{$DATA}...", ...)
          - pattern: $A = django.http.HttpResponse(..., request.$W, ...)
          - pattern: |
              $DATA = request.$W
              ...
              $INTERM = $STR + $DATA
              ...
              $A = django.http.HttpResponse(..., $INTERM, ...)
          - pattern: return django.http.HttpResponse(..., request.$W, ...)
          - pattern: |
              $DATA = request.$W
              ...
              $INTERM = f"...{$DATA}..."
              ...
              django.http.HttpResponse(..., $INTERM, ...)
          - pattern: |
              $DATA = request.$W
              ...
              django.http.HttpResponse(..., $STR + $DATA, ...)
          - pattern: |
              $DATA = request.$W
              ...
              $INTERM = $STR + $DATA
              ...
              django.http.HttpResponse(..., $INTERM, ...)

Examples

reflected-data-httpresponse.py

import urllib
from django.db.models import Q
from django.auth import User
from django.http import HttpResponse, HttpResponseBadRequest
from django.utils.translation import ugettext as _

from org import engines, manageNoEngine, genericApiException

def search_certificates(request):
    # ruleid: reflected-data-httpresponse
    user_filter = request.GET.get("user", "")
    if not user_filter:
        msg = _("user is not given.")
        return HttpResponseBadRequest(msg)


    user = User.objects.get(Q(email=user_filter) | Q(username=user_filter))
    if user.DoesNotExist:
        return HttpResponse(_("user '{user}' does not exist").format(user_filter))

def previewNode(request, uid):
    """Preview evaluante node"""
    try:
        if uid in engines:
            # ok: reflected-data-httpresponse
            _nodeId = request.data.get('nodeId')
            engines[uid].stoppable = True
            _res = engines[uid].model.previewNode(_nodeId)
            if _res is None:
                return HttpResponse('', status=204)
            return HttpResponse(_res)
        return manageNoEngine()
    except Exception as e:
        return genericApiException(e, engines[uid])
    finally:
        engines[uid].stoppable = False

def inline_test(request):
    # ruleid: reflected-data-httpresponse
    return HttpResponse("Received {}".format(request.POST.get('message')))