-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python: Promote Template Injection query from experimental #17922
base: main
Are you sure you want to change the base?
Python: Promote Template Injection query from experimental #17922
Conversation
`Cheetah` was excluded as it was last updated 15 years ago and its documentation links are dead.
b487f4c
to
2d04af8
Compare
db819bf
to
9377747
Compare
9377747
to
66e173c
Compare
QHelp previews: python/ql/src/Security/CWE-074/TemplateInjection.qhelpServer Side Template InjectionA template from a server templating engine such as Jinja constructed from user input can allow the user to execute arbitrary code using certain template features. It can also allow for cross-site scripting. RecommendationEnsure that an untrusted value is not used to directly construct a template. Jinja also provides a ExampleIn the following case, from django.urls import path
from django.http import HttpResponse
from jinja2 import Template, escape
def a(request):
template = request.GET['template']
# BAD: Template is constructed from user input.
t = Template(template)
name = request.GET['name']
html = t.render(name=escape(name))
return HttpResponse(html)
urlpatterns = [
path('a', a),
] The following is an example of a string that could be used to cause remote code execution when interpreted as a template: {% for s in ().__class__.__base__.__subclasses__() %}{% if "warning" in s.__name__ %}{{s()._module.__builtins__['__import__']('os').system('cat /etc/passwd') }}{% endif %}{% endfor %}
In the following case, user input is not used to construct the template; rather is only used for as the parameters to render the template, which is safe. from django.urls import path
from django.http import HttpResponse
from jinja2 import Template, escape
def a(request):
# GOOD: Template is a constant, not constructed from user input
t = Template("Hello, {{name}}!")
name = request.GET['name']
html = t.render(name=escape(name))
return HttpResponse(html)
urlpatterns = [
path('a', a),
] In the following case, a from django.urls import path
from django.http import HttpResponse
from jinja2 import escape
from jinja2.sandbox import SandboxedEnvironment
def a(request):
env = SandboxedEnvironment()
template = request.GET['template']
# GOOD: A sandboxed environment is used to construct the template.
t = env.from_string(template)
name = request.GET['name']
html = t.render(name=escape(name))
return HttpResponse(html)
urlpatterns = [
path('a', a),
] References
|
f6ef223
to
190afe6
Compare
Promotes the Template Injection query, originally submitted to the experimental query pack here.
Fixes a modeled
Jinja2
sink to properly refer toEnvironment().from_string()
; and promotes sinks from the other template frameworks included in the experimental version.Excludes the
Cheetah
package as its documentation links are dead and its last update was 15 years ago.