Autoescaping and context-aware HTML output¶
Autoescaping converts characters in a template value so the browser treats them as data in the intended HTML context. Disabling it can allow untrusted content to become markup and lead to cross-site scripting. The feature itself is protective; the issue is an unsafe output path or an inappropriate trust override.
Keep HTML autoescaping enabled¶
This example uses Python with Jinja in an environment dedicated to HTML output. The template source is a fixed, developer-owned string; comment is untrusted text.
Unsafe: render the value without escaping.
from jinja2 import Environment
env = Environment(autoescape=False)
page = env.from_string('<p>{{ comment }}</p>').render(comment=comment)
Safer for this HTML text context: enable autoescaping.
from jinja2 import Environment
env = Environment(autoescape=True)
page = env.from_string('<p>{{ comment }}</p>').render(comment=comment)
Jinja then escapes the value inserted into the paragraph. For applications rendering multiple file types, configure the documented select_autoescape policy deliberately and test string templates as well. See the Jinja autoescaping reference.
Do not apply safe, Markup or similar trust overrides to ordinary user input. If rich HTML is an intentional feature, sanitize it using an explicit allowed-content policy before granting that trust. Escaping an HTML text node does not make a value safe inside arbitrary JavaScript, CSS or URL contexts. Avoid placing untrusted values in executable contexts and use the framework's purpose-built serialization helpers where appropriate. OWASP's XSS prevention guidance explains these context boundaries.
Check the output¶
Render the harmless comment <b>Demo</b> and assert that the result contains escaped angle brackets, not a nested b element. Test apostrophes, ampersands, Unicode and empty input. Repeat the test through the actual view path so a later template override cannot bypass the policy unnoticed.
Autoescaping does not make untrusted template source safe to execute. Keep user content in template variables; do not build or compile template source from it. Continue with XSS, template injection and unsafe innerHTML.
Assess the real output context and framework configuration. A single escaping call or a clean source scan is not proof that every response path is protected.