Skip to content

Commit 054b706

Browse files
committedApr 19, 2018
Skip making self a TaintedNode, vuln test for it, flake8 vuln_test, 88->89%
1 parent 687626b commit 054b706

File tree

6 files changed

+70
-19
lines changed

6 files changed

+70
-19
lines changed
 

‎.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
- id: check-ast
99
- id: check-symlinks
1010
- id: flake8
11-
args: ['--ignore=E501']
11+
args: ['--exclude=examples/*', '--ignore=E501,E741']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
def my_data(self, foo, bar):
4+
return redirect(self.something)

‎pyt/framework_adaptor.py

+21-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
from .ast_helper import Arguments
66
from .expr_visitor import make_cfg
77
from .module_definitions import project_definitions
8-
from .node_types import TaintedNode
8+
from .node_types import (
9+
AssignmentNode,
10+
TaintedNode
11+
)
912

1013

1114
class FrameworkAdaptor():
@@ -37,19 +40,27 @@ def get_func_cfg_with_tainted_args(self, definition):
3740
first_node_after_args = func_cfg.nodes[1]
3841
first_node_after_args.ingoing = list()
3942

40-
# We're just gonna give all the tainted args the lineno of the def
43+
# We are just going to give all the tainted args the lineno of the def
4144
definition_lineno = definition.node.lineno
4245

4346
# Taint all the arguments
44-
for arg in args:
45-
tainted_node = TaintedNode(arg, arg,
46-
None, [],
47-
line_number=definition_lineno,
48-
path=definition.path)
49-
function_entry_node.connect(tainted_node)
47+
for i, arg in enumerate(args):
48+
node_type = TaintedNode
49+
if i == 0 and arg == 'self':
50+
node_type = AssignmentNode
51+
52+
arg_node = node_type(
53+
label=arg,
54+
left_hand_side=arg,
55+
ast_node=None,
56+
right_hand_side_variables=[],
57+
line_number=definition_lineno,
58+
path=definition.path
59+
)
60+
function_entry_node.connect(arg_node)
5061
# 1 and not 0 so that Entry Node remains first in the list
51-
func_cfg.nodes.insert(1, tainted_node)
52-
tainted_node.connect(first_node_after_args)
62+
func_cfg.nodes.insert(1, arg_node)
63+
arg_node.connect(first_node_after_args)
5364

5465
return func_cfg
5566

‎pyt/node_types.py

+4
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ def __repr__(self):
176176

177177

178178
class TaintedNode(AssignmentNode):
179+
"""CFG Node that represents a tainted node.
180+
181+
Only created in framework_adaptor.py and only used in `identify_triggers` of vulnerabilities.py
182+
"""
179183
pass
180184

181185

‎tests/vulnerabilities_test.py

+39-7
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
from pyt.constraint_table import initialize_constraint_table
1616
from pyt.fixed_point import analyse
1717
from pyt.framework_adaptor import FrameworkAdaptor
18-
from pyt.framework_helper import(
18+
from pyt.framework_helper import (
1919
is_django_view_function,
20-
is_flask_route_function
20+
is_flask_route_function,
21+
is_function
2122
)
2223
from pyt.node_types import Node
2324
from pyt.reaching_definitions_taint import ReachingDefinitionsTaintAnalysis
@@ -95,17 +96,15 @@ def test_find_triggers(self):
9596
l = vulnerabilities.find_triggers(XSS1.nodes, trigger_words)
9697
self.assert_length(l, expected_length=1)
9798

98-
9999
def test_find_sanitiser_nodes(self):
100100
cfg_node = Node(None, None, line_number=None, path=None)
101-
sanitiser_tuple = vulnerabilities.Sanitiser('escape', cfg_node)
101+
sanitiser_tuple = vulnerabilities.Sanitiser('escape', cfg_node)
102102
sanitiser = 'escape'
103103

104104
result = list(vulnerabilities.find_sanitiser_nodes(sanitiser, [sanitiser_tuple]))
105105
self.assert_length(result, expected_length=1)
106106
self.assertEqual(result[0], cfg_node)
107107

108-
109108
def test_build_sanitiser_node_dict(self):
110109
self.cfg_create_from_file('examples/vulnerable_code/XSS_sanitised.py')
111110
cfg_list = [self.cfg]
@@ -114,7 +113,7 @@ def test_build_sanitiser_node_dict(self):
114113

115114
cfg = cfg_list[1]
116115

117-
cfg_node = Node(None, None, line_number=None, path=None)
116+
cfg_node = Node(None, None, line_number=None, path=None)
118117
sinks_in_file = [vulnerabilities.TriggerNode('replace', ['escape'], cfg_node)]
119118

120119
sanitiser_dict = vulnerabilities.build_sanitiser_node_dict(cfg, sinks_in_file)
@@ -142,7 +141,6 @@ def run_analysis(self, path):
142141
)
143142
)
144143

145-
146144
def test_find_vulnerabilities_assign_other_var(self):
147145
vulnerabilities = self.run_analysis('examples/vulnerable_code/XSS_assign_to_other_var.py')
148146
self.assert_length(vulnerabilities, expected_length=1)
@@ -555,3 +553,37 @@ def test_django_view_param(self):
555553
~call_1 = ret_render(request, 'templates/xss.html', 'param'param)
556554
"""
557555
self.assertTrue(self.string_compare_alpha(vulnerability_description, EXPECTED_VULNERABILITY_DESCRIPTION))
556+
557+
558+
class EngineEveryTest(BaseTestCase):
559+
def run_empty(self):
560+
return
561+
562+
def run_analysis(self, path):
563+
self.cfg_create_from_file(path)
564+
cfg_list = [self.cfg]
565+
566+
FrameworkAdaptor(cfg_list, [], [], is_function)
567+
initialize_constraint_table(cfg_list)
568+
569+
analyse(cfg_list, analysis_type=ReachingDefinitionsTaintAnalysis)
570+
571+
trigger_word_file = os.path.join(
572+
'pyt',
573+
'vulnerability_definitions',
574+
'all_trigger_words.pyt'
575+
)
576+
577+
return vulnerabilities.find_vulnerabilities(
578+
cfg_list,
579+
ReachingDefinitionsTaintAnalysis,
580+
UImode.NORMAL,
581+
VulnerabilityFiles(
582+
default_blackbox_mapping_file,
583+
trigger_word_file
584+
)
585+
)
586+
587+
def test_self_is_not_tainted(self):
588+
vulnerabilities = self.run_analysis('examples/example_inputs/def_with_self_as_first_arg.py')
589+
self.assert_length(vulnerabilities, expected_length=0)

‎tox.ini

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ deps = -rrequirements-dev.txt
77
commands =
88
coverage erase
99
coverage run tests
10-
coverage report --show-missing --fail-under 88
10+
coverage report --show-missing --fail-under 89
1111
pre-commit run

0 commit comments

Comments
 (0)