Home Features Philosophy Docs Blog Errors Security Examples FAQ
DJE-001 Critical Security

Using mark_safe() with f-strings or user input

Error message

Potential XSS vulnerability: mark_safe() used with dynamic content

Using mark_safe() with f-strings or any user-controlled values creates a cross-site scripting (XSS) vulnerability. An attacker can inject arbitrary HTML and JavaScript into the page. This is one of the most common and dangerous security mistakes in Django template development.

security template xss

Affected versions: >=0.2.0

Solutions

Before (problematic)
from django.utils.safestring import mark_safe

def render_badge(user_name):
    return mark_safe(f'<span class="badge">{user_name}</span>')
After (fixed)
from django.utils.html import format_html

def render_badge(user_name):
    return format_html('<span class="badge">{}</span>', user_name)

Before (problematic)
from django.utils.safestring import mark_safe

def render_config(config_dict):
    return mark_safe(f'<script>var config = {config_dict};</script>')
After (fixed)
import json
from django.utils.html import format_html

def render_config(config_dict):
    safe_json = json.dumps(config_dict)
    return format_html(
        '<script>var config = {};</script>',
        mark_safe(safe_json)  # json.dumps output is safe
    )