Template XSS Protection Disabled

ID

python.template_xss_protection_disabled

Severity

high

Resource

Misconfiguration

Language

Python

Tags

CWE:80, NIST.SP.800-53, OWASP:2021:A3, OWASP:2021:A5, PCI-DSS:6.5.7

Description

Improper configurations or misuse of Python’s templating system can disable XSS protection, exposing applications to cross-site scripting attacks.

Rationale

Cross-Site Scripting (XSS) is a vulnerability that occurs when an application includes untrusted data in a web page without proper validation or escaping.

Python’s templating system is designed with built-in protections to prevent cross-site scripting (XSS) vulnerabilities. These protections automatically escape HTML input, ensuring that user-supplied content is not executed as code on the client side.

However, developers may inadvertently disable these protections by marking content as "safe" or bypassing the template engine, increasing the risk of XSS attacks. Some common misconfigurations and practices can lead to such vulnerabilities:

Template Variables In Dangerous Locations

Unquoted Variable In HTML Attribute

When an HTML attribute value is unquoted, it can lead to parsing issues or security vulnerabilities such as injection attacks. Quoting attribute values is a best practice to ensure integrity and security.

See the following template example:

<input type=text name=username value={{ username }}>

If username includes spaces or special characters, it may break the HTML structure or lead to unexpected behavior.

Variable In Href Attribute

When using template variables in href attributes, there’s a risk of allowing JavaScript URIs, which can lead to Cross-Site Scripting (XSS) vulnerabilities. HTML escaping doesn’t mitigate this risk because it doesn’t validate the URI scheme itself.

See the following template example:

<a href="{{ user_input }}">Click here</a>

If user_input contains "javascript:alert('XSS')" it could execute a script.

Variable In Script Block

When placing template variables directly into a JavaScript block, there’s a risk of code injection, which can lead to XSS vulnerabilities. HTML escaping doesn’t protect against this risk because JavaScript can execute without relying on special HTML characters.

<script>
    var userInput = {{ user_input }};
</script>

If user_input contains malicious code like alert('XSS');, it can execute in the context of your page.

Template Unescaped Variables

These issues are reported with a lower severity degree.

Safe and Safeseq Filters

These filters mark a string or sequence as safe, preventing it from being auto-escaped in a Django template.

<p>{{ user_inputs|safeseq|join:", " }}</p>

Autoescape Off Block

Using the {% autoescape off %} block within your templates disables the automatic HTML escaping feature, allowing content to be rendered as raw HTML. This can be useful for certain scenarios but poses significant security risks if not handled carefully.

{% autoescape off %}
{{ user_input }}
{% endautoescape %}

In this example, any HTML in user_input would be rendered directly without escaping.

Remediation

Carefully review every issue addressed by this detector to ensure that the unescaped HTML code is safe.

To effectively address XSS vulnerabilities when using Python templates enable all the autoescape settings.

References