Skip to content
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

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

joefarebrother
Copy link
Contributor

@joefarebrother joefarebrother commented Nov 6, 2024

Promotes the Template Injection query, originally submitted to the experimental query pack here.

Fixes a modeled Jinja2 sink to properly refer to Environment().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.

@github-actions github-actions bot added the Python label Nov 6, 2024
@joefarebrother joefarebrother force-pushed the python-promote-template-injection branch from b487f4c to 2d04af8 Compare November 20, 2024 12:00
@joefarebrother joefarebrother force-pushed the python-promote-template-injection branch 2 times, most recently from db819bf to 9377747 Compare November 21, 2024 17:12
@joefarebrother joefarebrother force-pushed the python-promote-template-injection branch from 9377747 to 66e173c Compare November 21, 2024 17:16
Copy link
Contributor

github-actions bot commented Nov 21, 2024

QHelp previews:

python/ql/src/Security/CWE-074/TemplateInjection.qhelp

Server Side Template Injection

A 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.

Recommendation

Ensure that an untrusted value is not used to directly construct a template. Jinja also provides a SandboxedEnvironment that prohibits access to unsafe methods and attributes, that can be used if constructing a template from user input is absolutely necessary.

Example

In the following case, template is used to generate a Jinja2 template string. This can lead to remote code execution.

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 SandboxedEnvironment is used, preventing remote code execution.

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

@joefarebrother joefarebrother marked this pull request as ready for review November 21, 2024 17:26
@joefarebrother joefarebrother requested a review from a team as a code owner November 21, 2024 17:26
@joefarebrother joefarebrother force-pushed the python-promote-template-injection branch from f6ef223 to 190afe6 Compare November 21, 2024 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant