Skip to content

Commit 2bc8413

Browse files
bcallerBen Caller
authored and
Ben Caller
committedSep 5, 2018
Add colourful formatter "screen"
Prints vulnerabilities with ANSI colour codes for the terminal. Not crazily colourful: just tries to highlight the important stuff. Repeated filenames aren't printed. Colour scheme might not be to everyone's taste.
1 parent f56e761 commit 2bc8413

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed
 

‎.coveragerc

+1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ source =
1515
./tests
1616
omit =
1717
pyt/formatters/json.py
18+
pyt/formatters/screen.py
1819
pyt/formatters/text.py

‎pyt/formatters/screen.py

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
"""This formatter outputs the issues as color-coded text."""
2+
from ..vulnerabilities.vulnerability_helper import SanitisedVulnerability, UnknownVulnerability
3+
4+
RESET = '\033[0m'
5+
BOLD = '\033[1m'
6+
UNDERLINE = '\033[4m'
7+
DANGER = '\033[31m'
8+
GOOD = '\033[32m'
9+
HIGHLIGHT = '\033[45;1m'
10+
RED_ON_WHITE = '\033[31m\033[107m'
11+
12+
13+
def color(string, color_string):
14+
return color_string + str(string) + RESET
15+
16+
17+
def report(
18+
vulnerabilities,
19+
fileobj,
20+
print_sanitised,
21+
):
22+
"""
23+
Prints issues in color-coded text format.
24+
25+
Args:
26+
vulnerabilities: list of vulnerabilities to report
27+
fileobj: The output file object, which may be sys.stdout
28+
"""
29+
n_vulnerabilities = len(vulnerabilities)
30+
unsanitised_vulnerabilities = [v for v in vulnerabilities if not isinstance(v, SanitisedVulnerability)]
31+
n_unsanitised = len(unsanitised_vulnerabilities)
32+
n_sanitised = n_vulnerabilities - n_unsanitised
33+
heading = "{} vulnerabilit{} found{}.\n".format(
34+
'No' if n_unsanitised == 0 else n_unsanitised,
35+
'y' if n_unsanitised == 1 else 'ies',
36+
" (plus {} sanitised)".format(n_sanitised) if n_sanitised else "",
37+
)
38+
vulnerabilities_to_print = vulnerabilities if print_sanitised else unsanitised_vulnerabilities
39+
with fileobj:
40+
for i, vulnerability in enumerate(vulnerabilities_to_print, start=1):
41+
fileobj.write(vulnerability_to_str(i, vulnerability))
42+
43+
if n_unsanitised == 0:
44+
fileobj.write(color(heading, GOOD))
45+
else:
46+
fileobj.write(color(heading, DANGER))
47+
48+
49+
def vulnerability_to_str(i, vulnerability):
50+
lines = []
51+
lines.append(color('Vulnerability {}'.format(i), UNDERLINE))
52+
lines.append('File: {}'.format(color(vulnerability.source.path, BOLD)))
53+
lines.append(
54+
'User input at line {}, source "{}":'.format(
55+
vulnerability.source.line_number,
56+
color(vulnerability.source_trigger_word, HIGHLIGHT),
57+
)
58+
)
59+
lines.append('\t{}'.format(color(vulnerability.source.label, RED_ON_WHITE)))
60+
if vulnerability.reassignment_nodes:
61+
previous_path = None
62+
lines.append('Reassigned in:')
63+
for node in vulnerability.reassignment_nodes:
64+
if node.path != previous_path:
65+
lines.append('\tFile: {}'.format(node.path))
66+
previous_path = node.path
67+
label = node.label
68+
if (
69+
isinstance(vulnerability, SanitisedVulnerability) and
70+
node.label == vulnerability.sanitiser.label
71+
):
72+
label = color(label, GOOD)
73+
lines.append(
74+
'\t Line {}:\t{}'.format(
75+
node.line_number,
76+
label,
77+
)
78+
)
79+
if vulnerability.source.path != vulnerability.sink.path:
80+
lines.append('File: {}'.format(color(vulnerability.sink.path, BOLD)))
81+
lines.append(
82+
'Reaches line {}, sink "{}"'.format(
83+
vulnerability.sink.line_number,
84+
color(vulnerability.sink_trigger_word, HIGHLIGHT),
85+
)
86+
)
87+
lines.append('\t{}'.format(
88+
color(vulnerability.sink.label, RED_ON_WHITE)
89+
))
90+
if isinstance(vulnerability, SanitisedVulnerability):
91+
lines.append(
92+
'This vulnerability is {}{} by {}'.format(
93+
color('potentially ', BOLD) if not vulnerability.confident else '',
94+
color('sanitised', GOOD),
95+
color(vulnerability.sanitiser.label, BOLD),
96+
)
97+
)
98+
elif isinstance(vulnerability, UnknownVulnerability):
99+
lines.append(
100+
'This vulnerability is unknown due to "{}"'.format(
101+
color(vulnerability.unknown_assignment.label, BOLD),
102+
)
103+
)
104+
return '\n'.join(lines) + '\n\n'

0 commit comments

Comments
 (0)
Please sign in to comment.