python.django.security.locals-as-template-context.locals-as-template-context
semgrep
Author
4,549
Download Count*
License
Using 'locals()' as a context to 'render(...)' is extremely dangerous. This exposes Python functions to the template that were not meant to be exposed. An attacker could use these functions to execute code that was not intended to run and could compromise the application. (This is server-side template injection (SSTI)). Do not use 'locals()'. Instead, specify each variable in a dictionary or 'django.template.Context' object, like '{"var1": "hello"}' and use that instead.
Run Locally
Run in CI
Defintion
rules:
- id: locals-as-template-context
languages:
- python
message: "Using 'locals()' as a context to 'render(...)' is extremely dangerous.
This exposes Python functions to the template that were not meant to be
exposed. An attacker could use these functions to execute code that was
not intended to run and could compromise the application. (This is
server-side template injection (SSTI)). Do not use 'locals()'. Instead,
specify each variable in a dictionary or 'django.template.Context' object,
like '{\"var1\": \"hello\"}' and use that instead."
metadata:
category: security
cwe:
- "CWE-96: Improper Neutralization of Directives in Statically Saved
Code ('Static Code Injection')"
owasp:
- A03:2021 - Injection
references:
- https://docs.djangoproject.com/en/3.2/ref/settings/#templates
- https://docs.djangoproject.com/en/3.2/topics/templates/#django.template.backends.django.DjangoTemplates
- https://docs.djangoproject.com/en/3.2/ref/templates/api/#rendering-a-context
technology:
- django
subcategory:
- audit
likelihood: LOW
impact: HIGH
confidence: LOW
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
vulnerability_class:
- Code Injection
pattern-either:
- pattern: django.shortcuts.render(..., locals(...), ...)
- pattern: django.template.Template.render(..., locals(...), ...)
- patterns:
- pattern-inside: |
$CONTEXT = locals(...)
...
- pattern-either:
- pattern: django.shortcuts.render(..., $CONTEXT, ...)
- pattern: django.template.Template.render(..., $CONTEXT, ...)
severity: ERROR
Examples
locals-as-template-context.py
import base64
import mimetypes
import os
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from django.shortcuts import redirect, render
from django.views.decorators.csrf import csrf_exempt
from django.template import Template
# adapted from https://github.com/mpirnat/lets-be-bad-guys/blob/7cbf11014bfc6dc9e199dc0b8a64e4597bc2338f/badguys/vulnerable/views.py#L95
def file_access(request):
msg = request.GET.get('msg', '')
# ok: locals-as-template-context
return render(request, 'vulnerable/injection/file_access.html',
{'msg': msg})
def bad1(request):
# ruleid: locals-as-template-context
response = render(request, 'vulnerable/xss/form.html', locals())
response.set_cookie(key='monster', value='omnomnomnomnom!')
return response
def bad2(request, path='default'):
env = locals()
# ruleid: locals-as-template-context
return render(request, 'vulnerable/xss/path.html', env)
def bad3(request):
# ruleid: locals-as-template-context
response = Template.render(request, 'vulnerable/xss/form.html', locals())
response.set_cookie(key='monster', value='omnomnomnomnom!')
return response
def bad4(request, path='default'):
env = locals()
# ruleid: locals-as-template-context
return Template.render(request, 'vulnerable/xss/path.html', env)
Short Link: https://sg.run/L8XL