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:

  1. {{ 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, or

  • the 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.