Django template autoescaping converts supported HTML-sensitive characters in rendered values so ordinary text is not interpreted as markup.
Django templates: escape untrusted text at HTML output
Operation contract
The review heading receives a deliberately hostile-looking label. A standalone template Engine renders it with autoescaping enabled, and the program verifies that a literal script opening tag did not enter the output. The original label remains unchanged; escaping belongs to the output context rather than an irreversible rewrite of stored text.
Failure and ownership boundary
HTML text escaping is not a universal encoder for JavaScript, CSS, URL schemes or arbitrary attribute contexts. Marking a value safe can bypass the protection. This fixture uses a text node and no user-defined template source. Django forms: ASCII wire fields and cleaned domain values and Django CSRF checks: require the token without confusing it with identity solve different security boundaries.
Tested environment
Dependency check: this program was executed on CPython 3.14.6 with Django==5.2.17. Install these versions in a separate virtual environment. The download includes the recorded environment snapshot; no third-party package is part of the website runtime.
Working program
from django.template import Context, Engine
label = '<script>alert("receipt")</script>'
template = Engine(debug=False).from_string("<h2>{{ label }}</h2>")
rendered = template.render(Context({"label": label}, autoescape=True))
print("literal script tag:", "<script>" in rendered)
print("escaped tag:", "<script>" in rendered)
print("original preserved:", label.startswith("<script>"))Output
literal script tag: False
escaped tag: True
original preserved: TrueCosts and limits
Rendering scans the selected values and creates output text. A size limit on accepted labels bounds that work in an application; this fixed fixture alone does not impose such a policy on every view.
Common Mistakes
- Do not mark received text safe to fix unwanted escaping.
- HTML text escaping does not validate a URL or encode a JavaScript expression.
Connected lessons
Django forms: ASCII wire fields and cleaned domain values, Django CSRF checks: require the token without confusing it with identity, Python strings and bytes: reject decoding errors before parsing records.
Continue with Python template strings: escape text values before rendering HTML.
