Jinja is a popular, powerful, and extensible Python templating engine widely used in web frameworks like Flask and Django. Recently, a security vulnerability has been identified in Jinja affecting the xmlattr filter, officially tracked as CVE-2024-34064. This issue allows attackers to inject arbitrary attributes—potentially leading to cross-site scripting (XSS)—if application code mishandles how it accepts and renders template keys.

This article gives you a simple, step-by-step explanation of the bug, includes code snippets for clarity, shows how the vulnerability can be exploited, and references all the original sources. You’ll also learn what’s been fixed (_and what hasn’t_) and what you need to do to stay secure.

What is the xmlattr Filter?

Jinja's xmlattr filter is a useful template feature that takes a dictionary (Python dict) and renders its key/value pairs as HTML or XML attributes. For example, this code:

attr = {'class': 'btn', 'id': 'go'}

<button {{ attr|xmlattr }}>Click me</button>

Would render as

<button class="btn" id="go">Click me</button>

Normally, template authors assume keys like 'class' and 'id' are safe and trusted. However, trouble arises when user input finds its way into those *keys* instead of only the values.

The Core Issue

HTML and XML attribute names have strict rules: they cannot contain spaces, slashes (/), greater-than signs (&gt;), or equals (=) signs. If an attacker can inject a key with one of these forbidden characters, they can break out of the attribute, creating new attributes—or even executing malicious JavaScript.

This vulnerability is

- Serious if your *application allows user control over dictionary keys* (not just values) sent to xmlattr and then renders those attributes in HTML.

Not a risk if only values are user-controlled and keys are hardcoded by the developer.

The fix for CVE-2024-22195 closed a similar gap for spaces but did not prevent other forbidden characters like /, =, and &gt;. CVE-2024-34064 closes this loophole.

> Important: xmlattr is considered *unsafe* for untrusted keys in any version. Do not allow users to submit attribute keys!

Vulnerable Flask App Before Fix

from flask import Flask, render_template_string, request

app = Flask(__name__)

@app.route("/")
def home():
    # Danger: Both attribute key and value come from the user!
    key = request.args.get("key", "name")
    value = request.args.get("value", "Guest")
    # User input used directly as dict keys and values
    attr = {key: value}
    return render_template_string(
        '<input {{ attr|xmlattr }}>',
        attr=attr
    )

Exploit URL

http://localhost:500/?key=onfocus%2fonmouseover%3dalert(1)&value=x

- The key becomes: onfocus/onmouseover=alert(1)

Rendered Output (before fix)

<input onfocus/onmouseover=alert(1)="x">

Result: The attacker can get their JavaScript executed with events like onmouseover or onfocus.

What Did Jinja Fix?

- Fixed in version 3.1.4 (Release notes)
- Jinja now forbids all non-attribute characters in keys ( , /, >, =).

If you use a version older than 3.1.4, you are at risk!

Only Allow User Input in Values!

# SAFE: Keys are hard-coded/namespaced, only values come from user input
attr = {'id': user_submitted_id, 'class': user_selected_class}

import re

def is_safe_attribute_key(key):
    # Only allow alphanumerics, underscores, hyphens
    return re.match(r'^[a-zA-Z_][a-zA-Z-9_-]*$', key) is not None

---

References and Further Reading

- CVE-2024-34064 on GitHub Advisory Database
- Jinja 3.1.4 Release Notes
- CVE-2024-22195 NVD Entry
- Original Source Code Patch

Summary

- Never allow users to submit dictionary keys for use in xmlattr; only allow control over values.
- Upgrade Jinja to at least 3.1.4 to prevent this attack, even if you never let users provide keys.

Review legacy code for improper uses of xmlattr and validate all input.

Stay safe—give attackers as little control as possible!


Author: SecureNow Labs
Date: 2024-06


*This article is written exclusively for those wanting a simple and direct explanation of CVE-2024-34064. Please use responsibly and always patch your dependencies!*

Timeline

Published on: 05/06/2024 15:15:23 UTC
Last modified on: 06/10/2024 18:15:34 UTC