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
-
CWE-80 : Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS).