diff options
author | Ross Burton <ross.burton@intel.com> | 2018-11-26 15:05:58 +0000 |
---|---|---|
committer | Khem Raj <raj.khem@gmail.com> | 2018-11-27 11:05:22 -0800 |
commit | 23acce81f49c539fee668dc7405d6a1f51792062 (patch) | |
tree | 405dfdfdc2dc776175740c398019088c61f9945a | |
parent | 11c3566f104acb867362edb2baefd03b282b69bb (diff) | |
download | meta-openembedded-23acce81f49c539fee668dc7405d6a1f51792062.tar.gz |
bandit: add class to perform Bandit scans
Add a class to perform security scans of Python code using Bandit.
Signed-off-by: Ross Burton <ross.burton@intel.com>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
-rw-r--r-- | meta-python/classes/bandit.bbclass | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/meta-python/classes/bandit.bbclass b/meta-python/classes/bandit.bbclass new file mode 100644 index 000000000..dc1041e46 --- /dev/null +++ b/meta-python/classes/bandit.bbclass | |||
@@ -0,0 +1,63 @@ | |||
1 | # Class to scan Python code for security issues, using Bandit. | ||
2 | # | ||
3 | # $ bitbake python-foo -c bandit | ||
4 | # | ||
5 | # Writes the report to $DEPLOY_DIR/bandit/python-foo.html. | ||
6 | # No output if no issues found, a warning if issues found. | ||
7 | # | ||
8 | # https://github.com/PyCQA/bandit | ||
9 | |||
10 | # Default location of sources, based on standard distutils | ||
11 | BANDIT_SOURCE ?= "${S}/build" | ||
12 | |||
13 | # The report format to use. | ||
14 | # https://bandit.readthedocs.io/en/latest/formatters/index.html | ||
15 | BANDIT_FORMAT ?= "html" | ||
16 | |||
17 | # Whether a scan should be done every time the recipe is built. | ||
18 | # | ||
19 | # By default the scanning needs to be done explicitly, but by setting BANDIT_AUTO | ||
20 | # to 1 the scan will be done whenever the recipe it built. Note that you | ||
21 | # shouldn't set BANDIT_AUTO to 1 globally as it will then try to scan every | ||
22 | # recipe, including non-Python recipes, causing circular loops. | ||
23 | BANDIT_AUTO ?= "0" | ||
24 | |||
25 | # Whether Bandit finding issues results in a warning (0) or an error (1). | ||
26 | BANDIT_FATAL ?= "0" | ||
27 | |||
28 | do_bandit[depends] = "python3-bandit-native:do_populate_sysroot" | ||
29 | python do_bandit() { | ||
30 | import os, subprocess | ||
31 | try: | ||
32 | report = d.expand("${DEPLOY_DIR}/bandit/${PN}-${PV}.${BANDIT_FORMAT}") | ||
33 | os.makedirs(os.path.dirname(report), exist_ok=True) | ||
34 | |||
35 | args = ("bandit", | ||
36 | "--format", d.getVar("BANDIT_FORMAT"), | ||
37 | "--output", report, | ||
38 | "-ll", | ||
39 | "--recursive", d.getVar("BANDIT_SOURCE")) | ||
40 | subprocess.check_output(args, stderr=subprocess.STDOUT) | ||
41 | bb.note("Bandit found no issues (report written to %s)" % report) | ||
42 | except subprocess.CalledProcessError as e: | ||
43 | if e.returncode == 1: | ||
44 | if oe.types.boolean(d.getVar("BANDIT_FATAL")): | ||
45 | bb.error("Bandit found issues (report written to %s)" % report) | ||
46 | else: | ||
47 | bb.warn("Bandit found issues (report written to %s)" % report) | ||
48 | else: | ||
49 | bb.error("Bandit failed:\n" + e.output.decode("utf-8")) | ||
50 | } | ||
51 | |||
52 | python() { | ||
53 | before = "do_build" | ||
54 | after = "do_compile" | ||
55 | |||
56 | if oe.types.boolean(d.getVar("BANDIT_AUTO")): | ||
57 | bb.build.addtask("do_bandit", before, after, d) | ||
58 | else: | ||
59 | bb.build.addtask("do_bandit", None, after, d) | ||
60 | } | ||
61 | |||
62 | # TODO: store report in sstate | ||
63 | # TODO: a way to pass extra args or .bandit file, basically control -ll | ||