Skip to content

Commit 76379d4

Browse files
authored
Merge pull request #121 from omergunal/patch-2
Whitelist lines ending in # nosec
2 parents 3bf405b + 0928700 commit 76379d4

File tree

3 files changed

+37
-17
lines changed

3 files changed

+37
-17
lines changed

pyt/__main__.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ def parse_args(args):
142142
'(only JSON-formatted files are accepted)',
143143
type=str,
144144
default=False)
145+
parser.add_argument('--ignore-nosec', dest='ignore_nosec', action='store_true',
146+
help='do not skip lines with # nosec comments')
145147

146148
save_parser = subparsers.add_parser('save', help='Save menu.')
147149
save_parser.set_defaults(which='save')
@@ -192,7 +194,7 @@ def parse_args(args):
192194
return parser.parse_args(args)
193195

194196

195-
def analyse_repo(args, github_repo, analysis_type, ui_mode):
197+
def analyse_repo(args, github_repo, analysis_type, ui_mode, nosec_lines):
196198
cfg_list = list()
197199
directory = os.path.dirname(github_repo.path)
198200
project_modules = get_modules(directory)
@@ -215,7 +217,8 @@ def analyse_repo(args, github_repo, analysis_type, ui_mode):
215217
VulnerabilityFiles(
216218
args.blackbox_mapping_file,
217219
args.trigger_word_file
218-
)
220+
),
221+
nosec_lines
219222
)
220223
return vulnerabilities
221224

@@ -235,12 +238,23 @@ def main(command_line_args=sys.argv[1:]):
235238
elif args.trim_reassigned_in:
236239
ui_mode = UImode.TRIM
237240

241+
path = os.path.normpath(args.filepath)
238242
cfg_list = list()
243+
if args.ignore_nosec:
244+
nosec_lines = set()
245+
else:
246+
file = open(path, "r")
247+
lines = file.readlines()
248+
nosec_lines = set(
249+
lineno for
250+
(lineno, line) in enumerate(lines, start=1)
251+
if '#nosec' in line or '# nosec' in line)
252+
239253
if args.git_repos:
240254
repos = get_repos(args.git_repos)
241255
for repo in repos:
242256
repo.clone()
243-
vulnerabilities = analyse_repo(args, repo, analysis, ui_mode)
257+
vulnerabilities = analyse_repo(args, repo, analysis, ui_mode, nosec_lines)
244258
if args.json:
245259
json.report(vulnerabilities, sys.stdout)
246260
else:
@@ -263,8 +277,6 @@ def main(command_line_args=sys.argv[1:]):
263277
)
264278
exit()
265279

266-
path = os.path.normpath(args.filepath)
267-
268280
directory = None
269281
if args.project_root:
270282
directory = os.path.normpath(args.project_root)
@@ -305,8 +317,10 @@ def main(command_line_args=sys.argv[1:]):
305317
VulnerabilityFiles(
306318
args.blackbox_mapping_file,
307319
args.trigger_word_file
308-
)
320+
),
321+
nosec_lines
309322
)
323+
310324
if args.baseline:
311325
vulnerabilities = get_vulnerabilities_not_in_baseline(vulnerabilities, args.baseline)
312326

pyt/vulnerabilities.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ def identify_triggers(
7373
cfg,
7474
sources,
7575
sinks,
76-
lattice
76+
lattice,
77+
nosec_lines
7778
):
7879
"""Identify sources, sinks and sanitisers in a CFG.
7980
@@ -89,12 +90,12 @@ def identify_triggers(
8990
tainted_nodes = filter_cfg_nodes(cfg, TaintedNode)
9091
tainted_trigger_nodes = [TriggerNode('Framework function URL parameter', None,
9192
node) for node in tainted_nodes]
92-
sources_in_file = find_triggers(assignment_nodes, sources)
93+
sources_in_file = find_triggers(assignment_nodes, sources, nosec_lines)
9394
sources_in_file.extend(tainted_trigger_nodes)
9495

9596
find_secondary_sources(assignment_nodes, sources_in_file, lattice)
9697

97-
sinks_in_file = find_triggers(cfg.nodes, sinks)
98+
sinks_in_file = find_triggers(cfg.nodes, sinks, nosec_lines)
9899

99100
sanitiser_node_dict = build_sanitiser_node_dict(cfg, sinks_in_file)
100101

@@ -170,7 +171,8 @@ def append_node_if_reassigned(
170171

171172
def find_triggers(
172173
nodes,
173-
trigger_words
174+
trigger_words,
175+
nosec_lines=set()
174176
):
175177
"""Find triggers from the trigger_word_list in the nodes.
176178
@@ -183,7 +185,8 @@ def find_triggers(
183185
"""
184186
trigger_nodes = list()
185187
for node in nodes:
186-
trigger_nodes.extend(iter(label_contains(node, trigger_words)))
188+
if node.line_number not in nosec_lines:
189+
trigger_nodes.extend(iter(label_contains(node, trigger_words)))
187190
return trigger_nodes
188191

189192

@@ -466,7 +469,8 @@ def find_vulnerabilities_in_cfg(
466469
lattice,
467470
ui_mode,
468471
blackbox_mapping,
469-
vulnerabilities_list
472+
vulnerabilities_list,
473+
nosec_lines
470474
):
471475
"""Find vulnerabilities in a cfg.
472476
@@ -482,7 +486,8 @@ def find_vulnerabilities_in_cfg(
482486
cfg,
483487
definitions.sources,
484488
definitions.sinks,
485-
lattice
489+
lattice,
490+
nosec_lines
486491
)
487492
for sink in triggers.sinks:
488493
for source in triggers.sources:
@@ -503,7 +508,8 @@ def find_vulnerabilities(
503508
cfg_list,
504509
analysis_type,
505510
ui_mode,
506-
vulnerability_files
511+
vulnerability_files,
512+
nosec_lines=set()
507513
):
508514
"""Find vulnerabilities in a list of CFGs from a trigger_word_file.
509515
@@ -518,7 +524,6 @@ def find_vulnerabilities(
518524
"""
519525
vulnerabilities = list()
520526
definitions = parse(vulnerability_files.triggers)
521-
522527
with open(vulnerability_files.blackbox_mapping) as infile:
523528
blackbox_mapping = json.load(infile)
524529
for cfg in cfg_list:
@@ -528,9 +533,9 @@ def find_vulnerabilities(
528533
Lattice(cfg.nodes, analysis_type),
529534
ui_mode,
530535
blackbox_mapping,
531-
vulnerabilities
536+
vulnerabilities,
537+
nosec_lines
532538
)
533539
with open(vulnerability_files.blackbox_mapping, 'w') as outfile:
534540
json.dump(blackbox_mapping, outfile, indent=4)
535-
536541
return vulnerabilities

tests/command_line_test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def test_no_args(self):
2828
[-m BLACKBOX_MAPPING_FILE] [-py2] [-l LOG_LEVEL]
2929
[-a ADAPTOR] [-db] [-dl DRAW_LATTICE [DRAW_LATTICE ...]]
3030
[-j] [-li | -re | -rt] [-ppm] [-b BASELINE]
31+
[--ignore-nosec]
3132
{save,github_search} ...\n""" + \
3233
"python -m pyt: error: one of the arguments " + \
3334
"-f/--filepath -gr/--git-repos is required\n"

0 commit comments

Comments
 (0)