Django is one of the most popular Python web frameworks, powering thousands of websites. But in late 2021, a sneaky vulnerability was discovered in a tool developers often use during development: the {% debug %} template tag. If you’ve used Django versions prior to the fixed releases, you could have exposed your project to cross-site scripting (XSS) — even without realizing it.

Let’s walk through how CVE-2022-22818 works, what the risks are, and how you can make sure your site is secure.

What is CVE-2022-22818?

CVE-2022-22818 is a vulnerability disclosed in January 2022, affecting several versions of Django:

Django 4.: Before 4..2

The issue is with the {% debug %} template tag. This tag is used to print the current template context variables to the page — super handy while debugging! But, if untrusted user values are present in the context, this information could be dumped to the browser without proper escaping, allowing for XSS (cross-site scripting) attacks.

What’s the danger?

If your context has unsanitized user input, {% debug %} would output it as raw HTML. An attacker could inject <script> tags or malicious HTML, which would then run in the browser of anyone viewing that page — potentially stealing cookies, hijacking sessions, or more.

Explaining the Core Issue

Here’s a simple look at what happened under the hood.

Suppose you’re developing and use

{% debug %}

If your context includes something a user submitted — for example, request.GET['name'] with a value like <script>alert("xss")</script> — here’s an example template:

<h1>Hello, {{ name }}</h1>
{% debug %}

If you visit /welcome?name=<script>alert('XSSed')</script>, the output of {% debug %} would show

context = {
    ...
    'name': "<script>alert('XSSed')</script>",
    ...
}

Because {% debug %} did not HTML-escape its output, this value is rendered raw in the browser. The attacker's script could execute as soon as the page loads.

Real-World Impact and Exploit

While the {% debug %} tag is intended for debugging and should not be present in production templates, it’s not uncommon for projects (especially those with less-experienced developers) to leave it in by mistake.

This makes CVE-2022-22818 a low-complexity, high-impact vulnerability:

Here’s a quick proof of concept you can try with an old Django project (be careful!)

1. Template Example — templates/debug_test.html:

Hi, {{ name }}

{% debug %}


`

http://127...1:800/debug_test?name=alert('pwned')

How was it fixed?

The Django team fixed this bug by ensuring the context displayed by {% debug %} is properly escaped. That means any HTML or JavaScript inserted via context variables gets shown as harmless text, not as executed code.

You can update Django with pip

pip install "django>=3.2.12"
# or pick the fixed version for your branch

References

- Django Security Advisory: CVE-2022-22818
- Django CVE-2022-22818 at MITRE
- Django issue tracker/PR

Recap

- {% debug %} in Django versions < 2.2.27, < 3.2.12, and < 4..2 can leak XSS if user data is in context.

Timeline

Published on: 02/03/2022 02:15:00 UTC
Last modified on: 02/22/2022 10:19:00 UTC