python.django.security.audit.xss.direct-use-of-httpresponse.direct-use-of-httpresponse

Author
7,344
Download Count*
License
Detected data rendered directly to the end user via 'HttpResponse' or a similar object. This bypasses Django's built-in cross-site scripting (XSS) defenses and could result in an XSS vulnerability. Use Django's template engine to safely render HTML.
Run Locally
Run in CI
Defintion
rules:
- id: direct-use-of-httpresponse
message: Detected data rendered directly to the end user via 'HttpResponse' or a
similar object. This bypasses Django's built-in cross-site scripting (XSS)
defenses and could result in an XSS vulnerability. Use Django's template
engine to safely render HTML.
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://docs.djangoproject.com/en/3.1/intro/tutorial03/#a-shortcut-render
- https://docs.djangoproject.com/en/3.1/topics/http/shortcuts/#render
category: security
technology:
- django
cwe2022-top25: true
cwe2021-top25: true
subcategory:
- audit
likelihood: LOW
impact: MEDIUM
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
languages:
- python
severity: WARNING
patterns:
- pattern-not: django.http.$ANY("...", ...)
- pattern-not: django.http.$ANY()
- pattern-not: django.http.$ANY(..., content=None, ...)
- pattern-not: django.http.$ANY(status=...)
- pattern-not: django.http.HttpResponseNotAllowed([...])
- pattern-either:
- patterns:
- pattern-either:
- pattern: django.http.HttpResponse(...)
- pattern: django.http.HttpResponseBadRequest(...)
- pattern: django.http.HttpResponseNotFound(...)
- pattern: django.http.HttpResponseForbidden(...)
- pattern: django.http.HttpResponseNotAllowed(...)
- pattern: django.http.HttpResponseGone(...)
- pattern: django.http.HttpResponseServerError(...)
- pattern-not: django.http.$ANY(...,content_type=$TYPE,...)
- patterns:
- pattern-either:
- pattern: django.http.HttpResponse(...,content_type=$TYPE,...)
- pattern: django.http.HttpResponseBadRequest(...,content_type=$TYPE,...)
- pattern: django.http.HttpResponseNotFound(...,content_type=$TYPE,...)
- pattern: django.http.HttpResponseForbidden(...,content_type=$TYPE,...)
- pattern: django.http.HttpResponseNotAllowed(...,content_type=$TYPE,...)
- pattern: django.http.HttpResponseGone(...,content_type=$TYPE,...)
- pattern: django.http.HttpResponseServerError(...,content_type=$TYPE,...)
- metavariable-regex:
metavariable: $TYPE
regex: .*[tT][eE][xX][tT]/[hH][tT][mM][lL].*
Examples
direct-use-of-httpresponse.py
import urllib
import json
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):
user_filter = request.GET.get("user", "")
if not user_filter:
# ok:direct-use-of-httpresponse
return HttpResponseBadRequest("user was not given")
user = User.objects.get(Q(email=user_filter) | Q(username=user_filter))
if user.DoesNotExist:
# ruleid:direct-use-of-httpresponse
return HttpResponseBadRequest(_("user '{user}' does not exist").format(user_filter))
def previewNode(request, uid):
"""Preview evaluante node"""
try:
if uid in engines:
_nodeId = request.data.get('nodeId')
engines[uid].stoppable = True
_res = engines[uid].model.previewNode(_nodeId)
if _res is None:
# ok:direct-use-of-httpresponse
return HttpResponse('', status=204)
# ruleid:direct-use-of-httpresponse
return HttpResponse(_res)
return manageNoEngine()
except Exception as e:
return genericApiException(e, engines[uid])
finally:
engines[uid].stoppable = False
def inline_test(request):
# ruleid:direct-use-of-httpresponse
return HttpResponse("Received {}".format(request.POST.get('message')))
def vote(request, question_id):
if request.method != "GET" and request.method != "POST":
# ruleid:direct-use-of-httpresponse
return HttpResponseBadRequest(
"This view can not handle method {0}\n".format(request.method), status=405
)
def endpoint():
# ok:direct-use-of-httpresponse
return HttpResponse(json.dumps({ 'status': 'ERROR', 'error': str(e) }), content_type='text/json')
def dangerous_endpoint():
# ruleid:direct-use-of-httpresponse
return HttpResponse(json.dumps({ 'status': 'ERROR', 'error': str(e) }), content_type='text/html')
Short Link: https://sg.run/EknN