updates
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
r"""
|
||||
==========================================
|
||||
B701: Test for not auto escaping in jinja2
|
||||
==========================================
|
||||
|
||||
Jinja2 is a Python HTML templating system. It is typically used to build web
|
||||
applications, though appears in other places well, notably the Ansible
|
||||
automation system. When configuring the Jinja2 environment, the option to use
|
||||
autoescaping on input can be specified. When autoescaping is enabled, Jinja2
|
||||
will filter input strings to escape any HTML content submitted via template
|
||||
variables. Without escaping HTML input the application becomes vulnerable to
|
||||
Cross Site Scripting (XSS) attacks.
|
||||
|
||||
Unfortunately, autoescaping is False by default. Thus this plugin test will
|
||||
warn on omission of an autoescape setting, as well as an explicit setting of
|
||||
false. A HIGH severity warning is generated in either of these scenarios.
|
||||
|
||||
:Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
>> Issue: Using jinja2 templates with autoescape=False is dangerous and can
|
||||
lead to XSS. Use autoescape=True to mitigate XSS vulnerabilities.
|
||||
Severity: High Confidence: High
|
||||
CWE: CWE-94 (https://cwe.mitre.org/data/definitions/94.html)
|
||||
Location: ./examples/jinja2_templating.py:11
|
||||
10 templateEnv = jinja2.Environment(autoescape=False,
|
||||
loader=templateLoader)
|
||||
11 Environment(loader=templateLoader,
|
||||
12 load=templateLoader,
|
||||
13 autoescape=False)
|
||||
14
|
||||
|
||||
>> Issue: By default, jinja2 sets autoescape to False. Consider using
|
||||
autoescape=True or use the select_autoescape function to mitigate XSS
|
||||
vulnerabilities.
|
||||
Severity: High Confidence: High
|
||||
CWE: CWE-94 (https://cwe.mitre.org/data/definitions/94.html)
|
||||
Location: ./examples/jinja2_templating.py:15
|
||||
14
|
||||
15 Environment(loader=templateLoader,
|
||||
16 load=templateLoader)
|
||||
17
|
||||
18 Environment(autoescape=select_autoescape(['html', 'htm', 'xml']),
|
||||
19 loader=templateLoader)
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
- `OWASP XSS <https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)>`__
|
||||
- https://realpython.com/primer-on-jinja-templating/
|
||||
- https://jinja.palletsprojects.com/en/2.11.x/api/#autoescaping
|
||||
- https://security.openstack.org/guidelines/dg_cross-site-scripting-xss.html
|
||||
- https://cwe.mitre.org/data/definitions/94.html
|
||||
|
||||
.. versionadded:: 0.10.0
|
||||
|
||||
.. versionchanged:: 1.7.3
|
||||
CWE information added
|
||||
|
||||
"""
|
||||
import ast
|
||||
|
||||
import bandit
|
||||
from bandit.core import issue
|
||||
from bandit.core import test_properties as test
|
||||
|
||||
|
||||
@test.checks("Call")
|
||||
@test.test_id("B701")
|
||||
def jinja2_autoescape_false(context):
|
||||
# check type just to be safe
|
||||
if isinstance(context.call_function_name_qual, str):
|
||||
qualname_list = context.call_function_name_qual.split(".")
|
||||
func = qualname_list[-1]
|
||||
if "jinja2" in qualname_list and func == "Environment":
|
||||
for node in ast.walk(context.node):
|
||||
if isinstance(node, ast.keyword):
|
||||
# definite autoescape = False
|
||||
if getattr(node, "arg", None) == "autoescape" and (
|
||||
getattr(node.value, "id", None) == "False"
|
||||
or getattr(node.value, "value", None) is False
|
||||
):
|
||||
return bandit.Issue(
|
||||
severity=bandit.HIGH,
|
||||
confidence=bandit.HIGH,
|
||||
cwe=issue.Cwe.CODE_INJECTION,
|
||||
text="Using jinja2 templates with autoescape="
|
||||
"False is dangerous and can lead to XSS. "
|
||||
"Use autoescape=True or use the "
|
||||
"select_autoescape function to mitigate XSS "
|
||||
"vulnerabilities.",
|
||||
)
|
||||
# found autoescape
|
||||
if getattr(node, "arg", None) == "autoescape":
|
||||
value = getattr(node, "value", None)
|
||||
if (
|
||||
getattr(value, "id", None) == "True"
|
||||
or getattr(value, "value", None) is True
|
||||
):
|
||||
return
|
||||
# Check if select_autoescape function is used.
|
||||
elif isinstance(value, ast.Call) and (
|
||||
getattr(value.func, "attr", None)
|
||||
== "select_autoescape"
|
||||
or getattr(value.func, "id", None)
|
||||
== "select_autoescape"
|
||||
):
|
||||
return
|
||||
else:
|
||||
return bandit.Issue(
|
||||
severity=bandit.HIGH,
|
||||
confidence=bandit.MEDIUM,
|
||||
cwe=issue.Cwe.CODE_INJECTION,
|
||||
text="Using jinja2 templates with autoescape="
|
||||
"False is dangerous and can lead to XSS. "
|
||||
"Ensure autoescape=True or use the "
|
||||
"select_autoescape function to mitigate "
|
||||
"XSS vulnerabilities.",
|
||||
)
|
||||
# We haven't found a keyword named autoescape, indicating default
|
||||
# behavior
|
||||
return bandit.Issue(
|
||||
severity=bandit.HIGH,
|
||||
confidence=bandit.HIGH,
|
||||
cwe=issue.Cwe.CODE_INJECTION,
|
||||
text="By default, jinja2 sets autoescape to False. Consider "
|
||||
"using autoescape=True or use the select_autoescape "
|
||||
"function to mitigate XSS vulnerabilities.",
|
||||
)
|
||||
Reference in New Issue
Block a user