Skip to content

Commit d02ee8e

Browse files
committed
Adding Bandit json parser
1 parent 2c7942a commit d02ee8e

File tree

4 files changed

+230
-0
lines changed

4 files changed

+230
-0
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ Now you will see a review with linting errors...
5353
```
5454
$ stylelint . | lintly --format=stylelint
5555
```
56+
- [bandit](https://github.com/PyCQA/bandit)
57+
```
58+
$ bandit -r . --format=json | lintly --format=bandit-json
59+
```
5660
5761
- [cfn-lint](https://github.com/aws-cloudformation/cfn-python-lint)
5862
```

lintly/parsers.py

+73
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,76 @@ def parse_violations(self, output):
234234
return violations
235235

236236

237+
class BanditJSONParser(BaseLintParser):
238+
"""
239+
Bandit JSON format:
240+
241+
[
242+
{
243+
"errors": [],
244+
"generated_at": "2021-01-07T23:39:39Z",
245+
"metrics": {
246+
"./lintly/formatters.py": {
247+
"CONFIDENCE.HIGH": 1.0,
248+
"CONFIDENCE.LOW": 0.0,
249+
"CONFIDENCE.MEDIUM": 0.0,
250+
"CONFIDENCE.UNDEFINED": 0.0,
251+
"SEVERITY.HIGH": 1.0,
252+
"SEVERITY.LOW": 0.0,
253+
"SEVERITY.MEDIUM": 0.0,
254+
"SEVERITY.UNDEFINED": 0.0,
255+
"loc": 31,
256+
"nosec": 0
257+
},
258+
"results": [
259+
{
260+
"code": "13 \n14 env = Environment(\n15 loader=FileSystemLoader(TEMPLATES_PATH),
261+
\n16 autoescape=False\n17 )\n",
262+
"filename": "./lintly/formatters.py",
263+
"issue_confidence": "HIGH",
264+
"issue_severity": "HIGH",
265+
"issue_text": "Using jinja2 templates with autoescape=False is dangerous and can lead to XSS.
266+
Use autoescape=True or use the select_autoescape function.",
267+
"line_number": 14,
268+
"line_range": [
269+
14,
270+
15,
271+
16
272+
],
273+
"more_info": "https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html",
274+
"test_id": "B701"
275+
"test_name": "jinja2_autoescape_false"
276+
}
277+
]
278+
]
279+
280+
"""
281+
282+
def parse_violations(self, output):
283+
284+
output = output.strip()
285+
if not output:
286+
return dict()
287+
288+
json_data = json.loads(output)
289+
290+
violations = collections.defaultdict(list)
291+
for violation_json in json_data["results"]:
292+
violation = Violation(
293+
line=violation_json["line_number"],
294+
column=0,
295+
code="{} ({})".format(
296+
violation_json["test_id"], violation_json["test_name"]
297+
),
298+
message=violation_json["issue_text"],
299+
)
300+
301+
path = self._normalize_path(violation_json["filename"])
302+
violations[path].append(violation)
303+
304+
return violations
305+
306+
237307
class CfnNagParser(BaseLintParser):
238308

239309
def parse_violations(self, output):
@@ -294,6 +364,9 @@ def parse_violations(self, output):
294364
# cfn-lint default formatter
295365
'cfn-lint': CfnLintParser(),
296366

367+
# Bandit Parser
368+
"bandit-json": BanditJSONParser(),
369+
297370
# cfn-nag JSON output
298371
'cfn-nag': CfnNagParser(),
299372
}

tests/linters_output/bandit-json.txt

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
{
2+
"errors": [],
3+
"generated_at": "2021-01-07T23:39:39Z",
4+
"metrics": {
5+
"./lintly/formatters.py": {
6+
"CONFIDENCE.HIGH": 1.0,
7+
"CONFIDENCE.LOW": 0.0,
8+
"CONFIDENCE.MEDIUM": 0.0,
9+
"CONFIDENCE.UNDEFINED": 0.0,
10+
"SEVERITY.HIGH": 1.0,
11+
"SEVERITY.LOW": 0.0,
12+
"SEVERITY.MEDIUM": 0.0,
13+
"SEVERITY.UNDEFINED": 0.0,
14+
"loc": 31,
15+
"nosec": 0
16+
},
17+
"_totals": {
18+
"CONFIDENCE.HIGH": 6.0,
19+
"CONFIDENCE.LOW": 0.0,
20+
"CONFIDENCE.MEDIUM": 0.0,
21+
"CONFIDENCE.UNDEFINED": 0.0,
22+
"SEVERITY.HIGH": 2.0,
23+
"SEVERITY.LOW": 4.0,
24+
"SEVERITY.MEDIUM": 0.0,
25+
"SEVERITY.UNDEFINED": 0.0,
26+
"loc": 2596,
27+
"nosec": 0
28+
}
29+
},
30+
"results": [
31+
{
32+
"code": "13 \n14 env = Environment(\n15 loader=FileSystemLoader(TEMPLATES_PATH),\n16 autoescape=False\n17 )\n",
33+
"filename": "./build/lib/lintly/formatters.py",
34+
"issue_confidence": "HIGH",
35+
"issue_severity": "HIGH",
36+
"issue_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.",
37+
"line_number": 14,
38+
"line_range": [
39+
14,
40+
15,
41+
16
42+
],
43+
"more_info": "https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html",
44+
"test_id": "B701",
45+
"test_name": "jinja2_autoescape_false"
46+
},
47+
{
48+
"code": "13 \n14 env = Environment(\n15 loader=FileSystemLoader(TEMPLATES_PATH),\n16 autoescape=False\n17 )\n",
49+
"filename": "./lintly/formatters.py",
50+
"issue_confidence": "HIGH",
51+
"issue_severity": "HIGH",
52+
"issue_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.",
53+
"line_number": 14,
54+
"line_range": [
55+
14,
56+
15,
57+
16
58+
],
59+
"more_info": "https://bandit.readthedocs.io/en/latest/plugins/b701_jinja2_autoescape_false.html",
60+
"test_id": "B701",
61+
"test_name": "jinja2_autoescape_false"
62+
},
63+
{
64+
"code": "47 builds.LintlyBuild(config, \"Some linter output\")\n48 assert GitHubBackend.call_args[1][\"context\"] == format_and_context[2]\n",
65+
"filename": "./tests/test_builds.py",
66+
"issue_confidence": "HIGH",
67+
"issue_severity": "LOW",
68+
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
69+
"line_number": 48,
70+
"line_range": [
71+
48
72+
],
73+
"more_info": "https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html",
74+
"test_id": "B101",
75+
"test_name": "assert_used"
76+
},
77+
{
78+
"code": "12 result = runner.invoke(cli.main, ['--help'])\n13 assert result.exit_code == 0\n14 assert not result.exception\n",
79+
"filename": "./tests/test_cli.py",
80+
"issue_confidence": "HIGH",
81+
"issue_severity": "LOW",
82+
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
83+
"line_number": 13,
84+
"line_range": [
85+
13
86+
],
87+
"more_info": "https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html",
88+
"test_id": "B101",
89+
"test_name": "assert_used"
90+
},
91+
{
92+
"code": "13 assert result.exit_code == 0\n14 assert not result.exception\n15 assert 'Usage' in result.output\n",
93+
"filename": "./tests/test_cli.py",
94+
"issue_confidence": "HIGH",
95+
"issue_severity": "LOW",
96+
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
97+
"line_number": 14,
98+
"line_range": [
99+
14
100+
],
101+
"more_info": "https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html",
102+
"test_id": "B101",
103+
"test_name": "assert_used"
104+
},
105+
{
106+
"code": "14 assert not result.exception\n15 assert 'Usage' in result.output\n16 \n",
107+
"filename": "./tests/test_cli.py",
108+
"issue_confidence": "HIGH",
109+
"issue_severity": "LOW",
110+
"issue_text": "Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.",
111+
"line_number": 15,
112+
"line_range": [
113+
15
114+
],
115+
"more_info": "https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html",
116+
"test_id": "B101",
117+
"test_name": "assert_used"
118+
}
119+
]
120+
}

tests/test_parsers.py

+33
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,39 @@ class Flake8ParserTestCase(ParserTestCaseMixin, unittest.TestCase):
9393
}
9494

9595

96+
class BanditJSONParserTestCase(ParserTestCaseMixin, unittest.TestCase):
97+
parser = PARSERS['bandit-json']
98+
linter_output_file_name = 'bandit-json.txt'
99+
expected_violations = {
100+
'build/lib/lintly/formatters.py': [
101+
{'line': 14, 'column': 0, 'code': 'B701 (jinja2_autoescape_false)',
102+
'message': ('Using jinja2 templates with autoescape=False is dangerous and can lead to XSS. '
103+
'Use autoescape=True or use the select_autoescape function to mitigate XSS vulnerabilities.')}
104+
],
105+
'lintly/formatters.py': [
106+
{'line': 14, 'column': 0, 'code': 'B701 (jinja2_autoescape_false)',
107+
'message': ('Using jinja2 templates with autoescape=False is dangerous and can lead to XSS. '
108+
'Use autoescape=True or use the select_autoescape function to mitigate XSS vulnerabilities.')}
109+
],
110+
'tests/test_builds.py': [
111+
{'line': 48, 'column': 0, 'code': 'B101 (assert_used)',
112+
'message': ('Use of assert detected. '
113+
'The enclosed code will be removed when compiling to optimised byte code.')}
114+
],
115+
'tests/test_cli.py': [
116+
{'line': 13, 'column': 0, 'code': 'B101 (assert_used)',
117+
'message': ('Use of assert detected. '
118+
'The enclosed code will be removed when compiling to optimised byte code.')},
119+
{'line': 14, 'column': 0, 'code': 'B101 (assert_used)',
120+
'message': ('Use of assert detected. '
121+
'The enclosed code will be removed when compiling to optimised byte code.')},
122+
{'line': 15, 'column': 0, 'code': 'B101 (assert_used)',
123+
'message': ('Use of assert detected. '
124+
'The enclosed code will be removed when compiling to optimised byte code.')}
125+
]
126+
}
127+
128+
96129
class PylintJSONParserTestCase(ParserTestCaseMixin, unittest.TestCase):
97130
parser = PARSERS['pylint-json']
98131
linter_output_file_name = 'pylint-json.txt'

0 commit comments

Comments
 (0)