Compose your HTML using an auto-escaping template language that, by default, escapes untrusted inputs for you.
For example, Django templates escape HTML special characters:
Clearly, user-submitted data shouldn't be trusted blindly and inserted directly into your Web pages, because a malicious user could use this kind of hole to do potentially bad things. This type of security exploit is called a Cross Site Scripting (XSS) attack.
To avoid this problem, you have two options:
- You can make sure to run each untrusted variable through the escape filter, which converts potentially harmful HTML characters to unharmful ones. This was the default solution in Django for its first few years, but the problem is that it puts the onus on you, the developer / template author, to ensure you're escaping everything. It's easy to forget to escape data.
- You can take advantage of Django's automatic HTML escaping. The remainder of this section describes how auto-escaping works.
By default in Django, every template automatically escapes the output of every variable tag.
There are also a variety of contextual auto-escaped templates which are a bit smarter, and can prevent XSS even when your templates contain embedded JavaScript, CSS, and URLs.
Closure templates says:
Contextual autoescaping works by augmenting Closure Templates to properly encode each dynamic value based on the context in which it appears, thus defending against XSS vulnerabilities in values that are controlled by an attacker.
Go's template language uses contextual autoescaping:
HTML templates treat data values as plain text which should be encoded so they can be safely embedded in an HTML document. The escaping is contextual, so actions can appear within JavaScript, CSS, and URI contexts.