HTML Escaping
When generating HTML from templates, there’s always a risk that a variable willinclude characters that affect the resulting HTML. There are two approaches:
manually escaping each variable; or
automatically escaping everything by default.
Jinja supports both. What is used depends on the application configuration.The default configuration is no automatic escaping; for various reasons:
Escaping everything except for safe values will also mean that Jinja isescaping variables known to not include HTML (e.g. numbers, booleans)which can be a huge performance hit.
The information about the safety of a variable is very fragile. It couldhappen that by coercing safe and unsafe values, the return value isdouble-escaped HTML.
Working with Manual Escaping
If manual escaping is enabled, it’s your responsibility to escapevariables if needed. What to escape? If you have a variable that _may_include any of the following chars (>
, <
, &
, or "
) youSHOULD escape it unless the variable contains well-formed and trustedHTML. Escaping works by piping the variable through the |e
filter:
{{ user.username|e }}
Working with Automatic Escaping
When automatic escaping is enabled, everything is escaped by default exceptfor values explicitly marked as safe. Variables and expressionscan be marked as safe either in:
the context dictionary by the application with
markupsafe.Markup
, orthe template, with the |safe filter
The main problem with this approach is that Python itself doesn’t have theconcept of tainted values; so whether a value is safe or unsafe can get lost.
If a value is not marked safe, auto-escaping will take place; which means thatyou could end up with double-escaped contents. Double-escaping is easy toavoid, however: just rely on the tools Jinja2 provides and don’t use builtinPython constructs such as str.format or the string modulo operator (%).
Jinja2 functions (macros, super, self.BLOCKNAME) always return templatedata that is marked as safe.
String literals in templates with automatic escaping are considered unsafebecause native Python strings (str
, unicode
, basestring
) are notmarkupsafe.Markup
strings with an html
attribute.