Do not flag new way of escaping in jinja2 plugin

Makes escaping using select_autoescape function valid by checking
for ast.Call instance and if func id == select_autoescape.

Example:

from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(['html', 'htm', 'xml']),
                    loader=PackageLoader('mypackage'))

Change-Id: I47c6b346332a6d9f7c4c57dd45ab7636c78996a1
Closes-Bug: #1684249
This commit is contained in:
Rajath Agasthya 2017-07-29 01:33:26 -07:00
parent ee9481dcdd
commit 8f1b50b5cc
3 changed files with 31 additions and 10 deletions

View File

@ -47,13 +47,16 @@ false. A HIGH severity warning is generated in either of these scenarios.
14 14
>> Issue: By default, jinja2 sets autoescape to False. Consider using >> Issue: By default, jinja2 sets autoescape to False. Consider using
autoescape=True to mitigate XSS vulnerabilities. autoescape=True or use the select_autoescape function to mitigate XSS
vulnerabilities.
Severity: High Confidence: High Severity: High Confidence: High
Location: ./examples/jinja2_templating.py:15 Location: ./examples/jinja2_templating.py:15
14 14
15 Environment(loader=templateLoader, 15 Environment(loader=templateLoader,
16 load=templateLoader) 16 load=templateLoader)
17 17
18 Environment(autoescape=select_autoescape(['html', 'htm', 'xml']),
19 loader=templateLoader)
.. seealso:: .. seealso::
@ -93,13 +96,19 @@ def jinja2_autoescape_false(context):
confidence=bandit.HIGH, confidence=bandit.HIGH,
text="Using jinja2 templates with autoescape=" text="Using jinja2 templates with autoescape="
"False is dangerous and can lead to XSS. " "False is dangerous and can lead to XSS. "
"Use autoescape=True to mitigate XSS " "Use autoescape=True or use the "
"select_autoescape function to mitigate XSS "
"vulnerabilities." "vulnerabilities."
) )
# found autoescape # found autoescape
if getattr(node, 'arg', None) == 'autoescape': if getattr(node, 'arg', None) == 'autoescape':
if (getattr(node.value, 'id', None) == 'True' or value = getattr(node, 'value', None)
getattr(node.value, 'value', None) is True): 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, 'id', None) == 'select_autoescape':
return return
else: else:
return bandit.Issue( return bandit.Issue(
@ -107,8 +116,9 @@ def jinja2_autoescape_false(context):
confidence=bandit.MEDIUM, confidence=bandit.MEDIUM,
text="Using jinja2 templates with autoescape=" text="Using jinja2 templates with autoescape="
"False is dangerous and can lead to XSS. " "False is dangerous and can lead to XSS. "
"Ensure autoescape=True to mitigate XSS " "Ensure autoescape=True or use the "
"vulnerabilities." "select_autoescape function to mitigate "
"XSS vulnerabilities."
) )
# We haven't found a keyword named autoescape, indicating default # We haven't found a keyword named autoescape, indicating default
# behavior # behavior
@ -116,5 +126,6 @@ def jinja2_autoescape_false(context):
severity=bandit.HIGH, severity=bandit.HIGH,
confidence=bandit.HIGH, confidence=bandit.HIGH,
text="By default, jinja2 sets autoescape to False. Consider " text="By default, jinja2 sets autoescape to False. Consider "
"using autoescape=True to mitigate XSS vulnerabilities." "using autoescape=True or use the select_autoescape "
"function to mitigate XSS vulnerabilities."
) )

View File

@ -1,5 +1,5 @@
import jinja2 import jinja2
from jinja2 import Environment from jinja2 import Environment, select_autoescape
templateLoader = jinja2.FileSystemLoader( searchpath="/" ) templateLoader = jinja2.FileSystemLoader( searchpath="/" )
something = '' something = ''
@ -14,3 +14,13 @@ Environment(loader=templateLoader,
Environment(loader=templateLoader, Environment(loader=templateLoader,
load=templateLoader) load=templateLoader)
Environment(loader=templateLoader, autoescape=select_autoescape())
Environment(loader=templateLoader,
autoescape=select_autoescape(['html', 'htm', 'xml']))
def fake_func():
return 'foobar'
Environment(loader=templateLoader, autoescape=fake_func())

View File

@ -441,8 +441,8 @@ class FunctionalTests(testtools.TestCase):
def test_jinja2_templating(self): def test_jinja2_templating(self):
'''Test jinja templating for potential XSS bugs.''' '''Test jinja templating for potential XSS bugs.'''
expect = { expect = {
'SEVERITY': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 0, 'HIGH': 4}, 'SEVERITY': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 0, 'HIGH': 5},
'CONFIDENCE': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 1, 'HIGH': 3} 'CONFIDENCE': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 2, 'HIGH': 3}
} }
self.check_example('jinja2_templating.py', expect) self.check_example('jinja2_templating.py', expect)