diff --git a/bandit/core/blacklisting.py b/bandit/core/blacklisting.py
index 6e015176e..a79b7274f 100644
--- a/bandit/core/blacklisting.py
+++ b/bandit/core/blacklisting.py
@@ -5,6 +5,7 @@
import ast
import fnmatch
+from bandit.core import cwemap
from bandit.core import issue
@@ -13,6 +14,7 @@ def report_issue(check, name):
severity=check.get("level", "MEDIUM"),
confidence="HIGH",
text=check["message"].replace("{name}", name),
+ cwe=cwemap.CWEMAP[check.get("id", "LEGACY")],
ident=name,
test_id=check.get("id", "LEGACY"),
)
diff --git a/bandit/core/cwemap.py b/bandit/core/cwemap.py
new file mode 100644
index 000000000..77144c9bb
--- /dev/null
+++ b/bandit/core/cwemap.py
@@ -0,0 +1,79 @@
+#
+# SPDX-License-Identifier: Apache-2.0
+from bandit.core import issue
+
+CWEMAP = {
+ "B000": issue.Cwe.NOTSET,
+ "LEGACY": issue.Cwe.NOTSET,
+ # Plugins
+ "B101": issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND,
+ "B102": issue.Cwe.OS_COMMAND_INJECTION,
+ "B103": issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT,
+ "B104": issue.Cwe.MULTIPLE_BINDS,
+ "B105": issue.Cwe.HARD_CODED_PASSWORD,
+ "B108": issue.Cwe.INSECURE_TEMP_FILE,
+ "B110": issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND,
+ "B112": issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND,
+ "B201": issue.Cwe.CODE_INJECTION,
+ "B324": issue.Cwe.BROKEN_CRYPTO,
+ "B501": issue.Cwe.IMPROPER_CERT_VALIDATION,
+ "B502": issue.Cwe.BROKEN_CRYPTO,
+ "B503": issue.Cwe.BROKEN_CRYPTO,
+ "B504": issue.Cwe.BROKEN_CRYPTO,
+ "B505": issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH,
+ "B506": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B507": issue.Cwe.IMPROPER_CERT_VALIDATION,
+ "B601": issue.Cwe.OS_COMMAND_INJECTION,
+ "B602": issue.Cwe.OS_COMMAND_INJECTION,
+ "B603": issue.Cwe.OS_COMMAND_INJECTION,
+ "B604": issue.Cwe.OS_COMMAND_INJECTION,
+ "B605": issue.Cwe.OS_COMMAND_INJECTION,
+ "B606": issue.Cwe.OS_COMMAND_INJECTION,
+ "B607": issue.Cwe.OS_COMMAND_INJECTION,
+ "B608": issue.Cwe.SQL_INJECTION,
+ "B609": issue.Cwe.IMPROPER_WILDCARD_NEUTRALIZATION,
+ "B611": issue.Cwe.SQL_INJECTION,
+ "B701": issue.Cwe.CODE_INJECTION,
+ "B702": issue.Cwe.BASIC_XSS,
+ "B703": issue.Cwe.BASIC_XSS,
+ # Calls
+ "B301": issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA,
+ "B302": issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA,
+ "B303": issue.Cwe.BROKEN_CRYPTO,
+ "B304": issue.Cwe.BROKEN_CRYPTO,
+ "B305": issue.Cwe.BROKEN_CRYPTO,
+ "B306": issue.Cwe.INSECURE_TEMP_FILE,
+ "B307": issue.Cwe.OS_COMMAND_INJECTION,
+ "B308": issue.Cwe.XSS,
+ "B309": issue.Cwe.CLEARTEXT_TRANSMISSION,
+ "B310": issue.Cwe.PATH_TRAVERSAL,
+ "B311": issue.Cwe.INSUFFICIENT_RANDOM_VALUES,
+ "B312": issue.Cwe.CLEARTEXT_TRANSMISSION,
+ "B313": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B314": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B315": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B316": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B317": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B318": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B319": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B320": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B321": issue.Cwe.CLEARTEXT_TRANSMISSION,
+ "B322": issue.Cwe.OS_COMMAND_INJECTION,
+ "B323": issue.Cwe.IMPROPER_CERT_VALIDATION,
+ "B325": issue.Cwe.INSECURE_TEMP_FILE,
+ # Imports
+ "B401": issue.Cwe.CLEARTEXT_TRANSMISSION,
+ "B402": issue.Cwe.CLEARTEXT_TRANSMISSION,
+ "B403": issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA,
+ "B404": issue.Cwe.OS_COMMAND_INJECTION,
+ "B405": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B406": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B407": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B408": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B409": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B410": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B411": issue.Cwe.IMPROPER_INPUT_VALIDATION,
+ "B412": issue.Cwe.IMPROPER_ACCESS_CONTROL,
+ "B413": issue.Cwe.BROKEN_CRYPTO,
+ "B414": issue.Cwe.BROKEN_CRYPTO,
+}
diff --git a/bandit/core/issue.py b/bandit/core/issue.py
index ef997b6d0..e9727a001 100644
--- a/bandit/core/issue.py
+++ b/bandit/core/issue.py
@@ -7,10 +7,77 @@
from bandit.core import constants
+class Cwe:
+ NOTSET = 0
+ IMPROPER_INPUT_VALIDATION = 20
+ PATH_TRAVERSAL = 22
+ OS_COMMAND_INJECTION = 78
+ XSS = 79
+ BASIC_XSS = 80
+ SQL_INJECTION = 89
+ CODE_INJECTION = 94
+ IMPROPER_WILDCARD_NEUTRALIZATION = 155
+ HARD_CODED_PASSWORD = 259
+ IMPROPER_ACCESS_CONTROL = 284
+ IMPROPER_CERT_VALIDATION = 295
+ CLEARTEXT_TRANSMISSION = 319
+ INADEQUATE_ENCRYPTION_STRENGTH = 326
+ BROKEN_CRYPTO = 327
+ INSUFFICIENT_RANDOM_VALUES = 330
+ INSECURE_TEMP_FILE = 377
+ DESERIALIZATION_OF_UNTRUSTED_DATA = 502
+ MULTIPLE_BINDS = 605
+ IMPROPER_CHECK_OF_EXCEPT_COND = 703
+ INCORRECT_PERMISSION_ASSIGNMENT = 732
+
+ MITRE_URL_PATTERN = "https://cwe.mitre.org/data/definitions/%s.html"
+
+ def __init__(self, id=NOTSET):
+ self.id = id
+
+ def link(self):
+ if self.id == Cwe.NOTSET:
+ return ""
+
+ return Cwe.MITRE_URL_PATTERN % str(self.id)
+
+ def __str__(self):
+ if self.id == Cwe.NOTSET:
+ return ""
+
+ return "CWE-%i (%s)" % (self.id, self.link())
+
+ def as_dict(self):
+ return (
+ {"id": self.id, "link": self.link()}
+ if self.id != Cwe.NOTSET
+ else {}
+ )
+
+ def as_jsons(self):
+ return str(self.as_dict())
+
+ def from_dict(self, data):
+ if "id" in data:
+ self.id = int(data["id"])
+ else:
+ self.id = Cwe.NOTSET
+
+ def __eq__(self, other):
+ return self.id == other.id
+
+ def __ne__(self, other):
+ return self.id != other.id
+
+ def __hash__(self):
+ return id(self)
+
+
class Issue:
def __init__(
self,
severity,
+ cwe=0,
confidence=constants.CONFIDENCE_DEFAULT,
text="",
ident=None,
@@ -19,6 +86,7 @@ def __init__(
col_offset=0,
):
self.severity = severity
+ self.cwe = Cwe(cwe)
self.confidence = confidence
if isinstance(text, bytes):
text = text.decode("utf-8")
@@ -33,11 +101,13 @@ def __init__(
def __str__(self):
return (
- "Issue: '%s' from %s:%s: Severity: %s Confidence: " "%s at %s:%i"
+ "Issue: '%s' from %s:%s: CWE: %s, Severity: %s Confidence: "
+ "%s at %s:%i"
) % (
self.text,
self.test_id,
(self.ident or self.test),
+ str(self.cwe),
self.severity,
self.confidence,
self.fname,
@@ -50,6 +120,7 @@ def __eq__(self, other):
match_types = [
"text",
"severity",
+ "cwe",
"confidence",
"fname",
"test",
@@ -119,6 +190,7 @@ def as_dict(self, with_code=True):
"test_name": self.test,
"test_id": self.test_id,
"issue_severity": self.severity,
+ "issue_cwe": self.cwe.as_dict(),
"issue_confidence": self.confidence,
"issue_text": self.text.encode("utf-8").decode("utf-8"),
"line_number": self.lineno,
@@ -134,6 +206,7 @@ def from_dict(self, data, with_code=True):
self.code = data["code"]
self.fname = data["filename"]
self.severity = data["issue_severity"]
+ self.cwe = cwe_from_dict(data["issue_cwe"])
self.confidence = data["issue_confidence"]
self.text = data["issue_text"]
self.test = data["test_name"]
@@ -143,6 +216,12 @@ def from_dict(self, data, with_code=True):
self.col_offset = data.get("col_offset", 0)
+def cwe_from_dict(data):
+ cwe = Cwe()
+ cwe.from_dict(data)
+ return cwe
+
+
def issue_from_dict(data):
i = Issue(severity=data["issue_severity"])
i.from_dict(data)
diff --git a/bandit/formatters/csv.py b/bandit/formatters/csv.py
index f0dbc08bf..81aa747db 100644
--- a/bandit/formatters/csv.py
+++ b/bandit/formatters/csv.py
@@ -54,6 +54,7 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
"test_name",
"test_id",
"issue_severity",
+ "issue_cwe",
"issue_confidence",
"issue_text",
"line_number",
@@ -68,6 +69,7 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
writer.writeheader()
for result in results:
r = result.as_dict(with_code=False)
+ r["issue_cwe"] = r["issue_cwe"]["link"]
r["more_info"] = docs_utils.get_url(r["test_id"])
writer.writerow(r)
diff --git a/bandit/formatters/html.py b/bandit/formatters/html.py
index 93262b4ef..ff6ea1f3e 100644
--- a/bandit/formatters/html.py
+++ b/bandit/formatters/html.py
@@ -258,6 +258,7 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
{test_name}: {test_text}
Test ID: {test_id}
Severity: {severity}
+ CWE: {cwe}
Confidence: {confidence}
File: {path}
Line number: {line_number}
@@ -357,6 +358,7 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
test_id=issue.test_id,
test_text=issue.text,
severity=issue.severity,
+ cwe=issue.cwe,
confidence=issue.confidence,
path=issue.fname,
code=code,
diff --git a/bandit/formatters/screen.py b/bandit/formatters/screen.py
index 0573b24ac..c1e204382 100644
--- a/bandit/formatters/screen.py
+++ b/bandit/formatters/screen.py
@@ -111,8 +111,13 @@ def _output_issue_str(
)
bits.append(
- "%s Severity: %s Confidence: %s"
- % (indent, issue.severity.capitalize(), issue.confidence.capitalize())
+ "%s Severity: %s CWE: %s Confidence: %s"
+ % (
+ indent,
+ issue.severity.capitalize(),
+ str(issue.cwe),
+ issue.confidence.capitalize(),
+ )
)
bits.append(
diff --git a/bandit/formatters/text.py b/bandit/formatters/text.py
index ec8e0c8bf..3e821d1d6 100644
--- a/bandit/formatters/text.py
+++ b/bandit/formatters/text.py
@@ -79,8 +79,13 @@ def _output_issue_str(
)
bits.append(
- "%s Severity: %s Confidence: %s"
- % (indent, issue.severity.capitalize(), issue.confidence.capitalize())
+ "%s Severity: %s CWE: %s Confidence: %s"
+ % (
+ indent,
+ issue.severity.capitalize(),
+ str(issue.cwe),
+ issue.confidence.capitalize(),
+ )
)
bits.append(
diff --git a/bandit/formatters/xml.py b/bandit/formatters/xml.py
index f3c2bc2ed..f3f9421bb 100644
--- a/bandit/formatters/xml.py
+++ b/bandit/formatters/xml.py
@@ -55,10 +55,14 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
root, "testcase", classname=issue.fname, name=test
)
- text = "Test ID: %s Severity: %s Confidence: %s\n%s\nLocation %s:%s"
+ text = (
+ "Test ID: %s Severity: %s CWE: %s Confidence: %s\n%s\n"
+ "Location %s:%s"
+ )
text = text % (
issue.test_id,
issue.severity,
+ issue.cwe,
issue.confidence,
issue.text,
issue.fname,
diff --git a/bandit/plugins/app_debug.py b/bandit/plugins/app_debug.py
index ae66459f3..3fbfd7db0 100644
--- a/bandit/plugins/app_debug.py
+++ b/bandit/plugins/app_debug.py
@@ -37,6 +37,7 @@
""" # noqa: E501
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -48,6 +49,7 @@ def flask_debug_true(context):
if context.check_call_arg_value("debug", "True"):
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B201"],
confidence=bandit.MEDIUM,
text="A Flask app appears to be run with debug=True, "
"which exposes the Werkzeug debugger and allows "
diff --git a/bandit/plugins/asserts.py b/bandit/plugins/asserts.py
index 7057873eb..4d401c9c5 100644
--- a/bandit/plugins/asserts.py
+++ b/bandit/plugins/asserts.py
@@ -50,6 +50,7 @@
import fnmatch
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -68,6 +69,7 @@ def assert_used(context, config):
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B101"],
confidence=bandit.HIGH,
text=(
"Use of assert detected. The enclosed code "
diff --git a/bandit/plugins/crypto_request_no_cert_validation.py b/bandit/plugins/crypto_request_no_cert_validation.py
index eed10ecf5..fc8da08d1 100644
--- a/bandit/plugins/crypto_request_no_cert_validation.py
+++ b/bandit/plugins/crypto_request_no_cert_validation.py
@@ -39,6 +39,7 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -53,6 +54,7 @@ def request_with_no_cert_validation(context):
if context.check_call_arg_value("verify", "False"):
issue = bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B501"],
confidence=bandit.HIGH,
text="Requests call with verify=False disabling SSL "
"certificate checks, security issue.",
diff --git a/bandit/plugins/django_sql_injection.py b/bandit/plugins/django_sql_injection.py
index 457bf8251..217accf4a 100644
--- a/bandit/plugins/django_sql_injection.py
+++ b/bandit/plugins/django_sql_injection.py
@@ -5,6 +5,7 @@
import ast
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -74,6 +75,7 @@ def django_extra_used(context):
if insecure:
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B611"],
confidence=bandit.MEDIUM,
text=description,
)
@@ -99,6 +101,7 @@ def django_rawsql_used(context):
if not isinstance(sql, ast.Str):
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B611"],
confidence=bandit.MEDIUM,
text=description,
)
diff --git a/bandit/plugins/django_xss.py b/bandit/plugins/django_xss.py
index 952d16fae..c46ef4074 100644
--- a/bandit/plugins/django_xss.py
+++ b/bandit/plugins/django_xss.py
@@ -5,6 +5,7 @@
import ast
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -219,7 +220,10 @@ def check_risk(node):
if not secure:
return bandit.Issue(
- severity=bandit.MEDIUM, confidence=bandit.HIGH, text=description
+ severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B703"],
+ confidence=bandit.HIGH,
+ text=description,
)
diff --git a/bandit/plugins/exec.py b/bandit/plugins/exec.py
index d42918887..3f89e035c 100644
--- a/bandit/plugins/exec.py
+++ b/bandit/plugins/exec.py
@@ -30,12 +30,14 @@
.. versionadded:: 0.9.0
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
def exec_issue():
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B102"],
confidence=bandit.HIGH,
text="Use of exec detected.",
)
diff --git a/bandit/plugins/general_bad_file_permissions.py b/bandit/plugins/general_bad_file_permissions.py
index 03b20f72b..f8b0ac421 100644
--- a/bandit/plugins/general_bad_file_permissions.py
+++ b/bandit/plugins/general_bad_file_permissions.py
@@ -47,6 +47,7 @@
import stat
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -73,6 +74,7 @@ def set_bad_file_permissions(context):
filename = "NOT PARSED"
return bandit.Issue(
severity=sev_level,
+ cwe=cwemap.CWEMAP["B103"],
confidence=bandit.HIGH,
text="Chmod setting a permissive mask %s on file (%s)."
% (oct(mode), filename),
diff --git a/bandit/plugins/general_bind_all_interfaces.py b/bandit/plugins/general_bind_all_interfaces.py
index ffdd02c04..3b53b8e5a 100644
--- a/bandit/plugins/general_bind_all_interfaces.py
+++ b/bandit/plugins/general_bind_all_interfaces.py
@@ -31,6 +31,7 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -40,6 +41,7 @@ def hardcoded_bind_all_interfaces(context):
if context.string_val == "0.0.0.0":
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B104"],
confidence=bandit.MEDIUM,
text="Possible binding to all interfaces.",
)
diff --git a/bandit/plugins/general_hardcoded_password.py b/bandit/plugins/general_hardcoded_password.py
index 2450adccd..930e8017d 100644
--- a/bandit/plugins/general_hardcoded_password.py
+++ b/bandit/plugins/general_hardcoded_password.py
@@ -6,6 +6,7 @@
import re
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -18,6 +19,7 @@
def _report(value):
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B105"],
confidence=bandit.MEDIUM,
text=("Possible hardcoded password: '%s'" % value),
)
diff --git a/bandit/plugins/general_hardcoded_tmp.py b/bandit/plugins/general_hardcoded_tmp.py
index bf42f7fab..c12762e8c 100644
--- a/bandit/plugins/general_hardcoded_tmp.py
+++ b/bandit/plugins/general_hardcoded_tmp.py
@@ -48,6 +48,7 @@
""" # noqa: E501
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -68,6 +69,7 @@ def hardcoded_tmp_directory(context, config):
if any(context.string_val.startswith(s) for s in tmp_dirs):
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B108"],
confidence=bandit.MEDIUM,
text="Probable insecure usage of temp file/directory.",
)
diff --git a/bandit/plugins/hashlib_new_insecure_functions.py b/bandit/plugins/hashlib_new_insecure_functions.py
index 3d3e7ac98..35b5d7338 100644
--- a/bandit/plugins/hashlib_new_insecure_functions.py
+++ b/bandit/plugins/hashlib_new_insecure_functions.py
@@ -28,6 +28,7 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -49,6 +50,7 @@ def hashlib_new(context):
):
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B324"],
confidence=bandit.HIGH,
text="Use of insecure MD4 or MD5 hash function.",
lineno=context.node.lineno,
diff --git a/bandit/plugins/injection_paramiko.py b/bandit/plugins/injection_paramiko.py
index 270f46b26..e92b3049d 100644
--- a/bandit/plugins/injection_paramiko.py
+++ b/bandit/plugins/injection_paramiko.py
@@ -36,6 +36,7 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -51,6 +52,7 @@ def paramiko_calls(context):
if context.call_function_name in ["exec_command"]:
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B601"],
confidence=bandit.MEDIUM,
text=issue_text,
)
diff --git a/bandit/plugins/injection_shell.py b/bandit/plugins/injection_shell.py
index 62d14e99b..8a6fb1591 100644
--- a/bandit/plugins/injection_shell.py
+++ b/bandit/plugins/injection_shell.py
@@ -6,8 +6,10 @@
import re
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
+
# yuck, regex: starts with a windows drive letter (eg C:)
# or one of our path delimeter characters (/, \, .)
full_path_match = re.compile(r"^(?:[A-Za-z](?=\:)|[\\\/\.])")
@@ -196,6 +198,7 @@ def subprocess_popen_with_shell_equals_true(context, config):
if sev == bandit.LOW:
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B602"],
confidence=bandit.HIGH,
text="subprocess call with shell=True seems safe, but "
"may be changed in the future, consider "
@@ -205,6 +208,7 @@ def subprocess_popen_with_shell_equals_true(context, config):
else:
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B602"],
confidence=bandit.HIGH,
text="subprocess call with shell=True identified, "
"security issue.",
@@ -284,6 +288,7 @@ def subprocess_without_shell_equals_true(context, config):
if not has_shell(context):
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B603"],
confidence=bandit.HIGH,
text="subprocess call - check for execution of untrusted "
"input.",
@@ -362,6 +367,7 @@ def any_other_function_with_shell_equals_true(context, config):
if has_shell(context):
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B604"],
confidence=bandit.LOW,
text="Function call with shell=True parameter identified, "
"possible security issue.",
@@ -448,6 +454,7 @@ def start_process_with_a_shell(context, config):
if sev == bandit.LOW:
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B605"],
confidence=bandit.HIGH,
text="Starting a process with a shell: "
"Seems safe, but may be changed in the future, "
@@ -456,6 +463,7 @@ def start_process_with_a_shell(context, config):
else:
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B605"],
confidence=bandit.HIGH,
text="Starting a process with a shell, possible injection"
" detected, security issue.",
@@ -544,6 +552,7 @@ def start_process_with_no_shell(context, config):
if config and context.call_function_name_qual in config["no_shell"]:
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B606"],
confidence=bandit.MEDIUM,
text="Starting a process without a shell.",
)
@@ -641,6 +650,7 @@ def start_process_with_partial_path(context, config):
if isinstance(node, ast.Str) and not full_path_match.match(node.s):
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B607"],
confidence=bandit.HIGH,
text="Starting a process with a partial executable path",
)
diff --git a/bandit/plugins/injection_sql.py b/bandit/plugins/injection_sql.py
index 7f7b4ccf5..712992c28 100644
--- a/bandit/plugins/injection_sql.py
+++ b/bandit/plugins/injection_sql.py
@@ -52,6 +52,7 @@
import re
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
from bandit.core import utils
@@ -104,6 +105,7 @@ def hardcoded_sql_expressions(context):
if _check_string(val[1]):
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B608"],
confidence=bandit.MEDIUM if val[0] else bandit.LOW,
text="Possible SQL injection vector through string-based "
"query construction.",
diff --git a/bandit/plugins/injection_wildcard.py b/bandit/plugins/injection_wildcard.py
index 0da922c48..c105e591f 100644
--- a/bandit/plugins/injection_wildcard.py
+++ b/bandit/plugins/injection_wildcard.py
@@ -94,10 +94,10 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
from bandit.plugins import injection_shell # NOTE(tkelsey): shared config
-
gen_config = injection_shell.gen_config
@@ -130,6 +130,7 @@ def linux_commands_wildcard_injection(context, config):
):
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B609"],
confidence=bandit.MEDIUM,
text="Possible wildcard injection in call: %s"
% context.call_function_name_qual,
diff --git a/bandit/plugins/insecure_ssl_tls.py b/bandit/plugins/insecure_ssl_tls.py
index c2d750839..bc09f0955 100644
--- a/bandit/plugins/insecure_ssl_tls.py
+++ b/bandit/plugins/insecure_ssl_tls.py
@@ -3,6 +3,7 @@
#
# SPDX-License-Identifier: Apache-2.0
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -105,6 +106,7 @@ def ssl_with_bad_version(context, config):
if context.check_call_arg_value("ssl_version", bad_ssl_versions):
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B502"],
confidence=bandit.HIGH,
text="ssl.wrap_socket call with insecure SSL/TLS protocol "
"version identified, security issue.",
@@ -114,6 +116,7 @@ def ssl_with_bad_version(context, config):
if context.check_call_arg_value("method", bad_ssl_versions):
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B502"],
confidence=bandit.HIGH,
text="SSL.Context call with insecure SSL/TLS protocol "
"version identified, security issue.",
@@ -132,6 +135,7 @@ def ssl_with_bad_version(context, config):
) or context.get_lineno_for_call_arg("ssl_version")
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B502"],
confidence=bandit.MEDIUM,
text="Function call with insecure SSL/TLS protocol "
"identified, possible security issue.",
@@ -189,6 +193,7 @@ def ssl_with_bad_defaults(context, config):
if val in bad_ssl_versions:
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B503"],
confidence=bandit.MEDIUM,
text="Function definition identified with insecure SSL/TLS "
"protocol version by default, possible security "
@@ -247,6 +252,7 @@ def ssl_with_no_version(context):
# tests for that (ssl_version is not specified).
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B504"],
confidence=bandit.MEDIUM,
text="ssl.wrap_socket call with no SSL/TLS protocol version "
"specified, the default SSLv23 could be insecure, "
diff --git a/bandit/plugins/jinja2_templates.py b/bandit/plugins/jinja2_templates.py
index d79600e9e..0edc38316 100644
--- a/bandit/plugins/jinja2_templates.py
+++ b/bandit/plugins/jinja2_templates.py
@@ -60,6 +60,7 @@
import ast
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -80,6 +81,7 @@ def jinja2_autoescape_false(context):
):
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B701"],
confidence=bandit.HIGH,
text="Using jinja2 templates with autoescape="
"False is dangerous and can lead to XSS. "
@@ -105,6 +107,7 @@ def jinja2_autoescape_false(context):
else:
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B701"],
confidence=bandit.MEDIUM,
text="Using jinja2 templates with autoescape="
"False is dangerous and can lead to XSS. "
@@ -116,6 +119,7 @@ def jinja2_autoescape_false(context):
# behavior
return bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B701"],
confidence=bandit.HIGH,
text="By default, jinja2 sets autoescape to False. Consider "
"using autoescape=True or use the select_autoescape "
diff --git a/bandit/plugins/mako_templates.py b/bandit/plugins/mako_templates.py
index e25b10a13..42b96160a 100644
--- a/bandit/plugins/mako_templates.py
+++ b/bandit/plugins/mako_templates.py
@@ -38,6 +38,7 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -53,6 +54,7 @@ def use_of_mako_templates(context):
# feature and thus each variable must be carefully sanitized.
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B702"],
confidence=bandit.HIGH,
text="Mako templates allow HTML/JS rendering by default and "
"are inherently open to XSS attacks. Ensure variables "
diff --git a/bandit/plugins/ssh_no_host_key_verification.py b/bandit/plugins/ssh_no_host_key_verification.py
index 88be94fe2..031f0e8a6 100644
--- a/bandit/plugins/ssh_no_host_key_verification.py
+++ b/bandit/plugins/ssh_no_host_key_verification.py
@@ -32,6 +32,7 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -48,6 +49,7 @@ def ssh_no_host_key_verification(context):
]:
issue = bandit.Issue(
severity=bandit.HIGH,
+ cwe=cwemap.CWEMAP["B507"],
confidence=bandit.MEDIUM,
text="Paramiko call with policy set to automatically trust "
"the unknown host key.",
diff --git a/bandit/plugins/try_except_continue.py b/bandit/plugins/try_except_continue.py
index 170f53c72..854fe6fc9 100644
--- a/bandit/plugins/try_except_continue.py
+++ b/bandit/plugins/try_except_continue.py
@@ -72,6 +72,7 @@ class (or no type). To accommodate this, the test may be configured to ignore
import ast
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -96,6 +97,7 @@ def try_except_continue(context, config):
if isinstance(node.body[0], ast.Continue):
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B112"],
confidence=bandit.HIGH,
text=("Try, Except, Continue detected."),
)
diff --git a/bandit/plugins/try_except_pass.py b/bandit/plugins/try_except_pass.py
index 5aae7986d..2ca64b214 100644
--- a/bandit/plugins/try_except_pass.py
+++ b/bandit/plugins/try_except_pass.py
@@ -70,6 +70,7 @@ class (or no type). To accommodate this, the test may be configured to ignore
import ast
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -94,6 +95,7 @@ def try_except_pass(context, config):
if isinstance(node.body[0], ast.Pass):
return bandit.Issue(
severity=bandit.LOW,
+ cwe=cwemap.CWEMAP["B110"],
confidence=bandit.HIGH,
text=("Try, Except, Pass detected."),
)
diff --git a/bandit/plugins/weak_cryptographic_key.py b/bandit/plugins/weak_cryptographic_key.py
index aafc1e45c..8e5dc1f94 100644
--- a/bandit/plugins/weak_cryptographic_key.py
+++ b/bandit/plugins/weak_cryptographic_key.py
@@ -35,6 +35,7 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -74,6 +75,7 @@ def _classify_key_size(config, key_type, key_size):
if key_size < size:
return bandit.Issue(
severity=level,
+ cwe=cwemap.CWEMAP["B505"],
confidence=bandit.HIGH,
text="%s key sizes below %d bits are considered breakable. "
% (key_type, size),
diff --git a/bandit/plugins/yaml_load.py b/bandit/plugins/yaml_load.py
index 2077790f5..3bc6603b9 100644
--- a/bandit/plugins/yaml_load.py
+++ b/bandit/plugins/yaml_load.py
@@ -36,6 +36,7 @@
"""
import bandit
+from bandit.core import cwemap
from bandit.core import test_properties as test
@@ -59,6 +60,7 @@ def yaml_load(context):
):
return bandit.Issue(
severity=bandit.MEDIUM,
+ cwe=cwemap.CWEMAP["B506"],
confidence=bandit.HIGH,
text="Use of unsafe yaml load. Allows instantiation of"
" arbitrary objects. Consider yaml.safe_load().",
diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py
index 39336eb48..ab2ada95e 100644
--- a/tests/functional/test_functional.py
+++ b/tests/functional/test_functional.py
@@ -765,6 +765,10 @@ def test_baseline_filter(self):
"filename": "{}/examples/flask_debug.py",
"issue_confidence": "MEDIUM",
"issue_severity": "HIGH",
+ "issue_cwe": {{
+ "id": 94,
+ "link": "https://cwe.mitre.org/data/definitions/94.html"
+ }},
"issue_text": "{}",
"line_number": 10,
"col_offset": 0,
diff --git a/tests/unit/core/test_blacklisting.py b/tests/unit/core/test_blacklisting.py
index 4aed78481..5e177602a 100644
--- a/tests/unit/core/test_blacklisting.py
+++ b/tests/unit/core/test_blacklisting.py
@@ -16,6 +16,7 @@ def test_report_issue(self):
self.assertIsInstance(issue_dict, dict)
self.assertEqual("B000", issue_dict["test_id"])
self.assertEqual("HIGH", issue_dict["issue_severity"])
+ self.assertEqual({}, issue_dict["issue_cwe"])
self.assertEqual("HIGH", issue_dict["issue_confidence"])
self.assertEqual("test name", issue_dict["issue_text"])
@@ -27,5 +28,6 @@ def test_report_issue_defaults(self):
self.assertIsInstance(issue_dict, dict)
self.assertEqual("LEGACY", issue_dict["test_id"])
self.assertEqual("MEDIUM", issue_dict["issue_severity"])
+ self.assertEqual({}, issue_dict["issue_cwe"])
self.assertEqual("HIGH", issue_dict["issue_confidence"])
self.assertEqual("test name", issue_dict["issue_text"])
diff --git a/tests/unit/core/test_issue.py b/tests/unit/core/test_issue.py
index 66853cf0c..dd1c72b9c 100644
--- a/tests/unit/core/test_issue.py
+++ b/tests/unit/core/test_issue.py
@@ -18,12 +18,15 @@ def test_issue_create(self):
def test_issue_str(self):
test_issue = _get_issue_instance()
+ expect = (
+ "Issue: 'Test issue' from B999:bandit_plugin:"
+ " CWE: %s,"
+ " Severity: MEDIUM "
+ "Confidence: MEDIUM at code.py:1"
+ )
+
self.assertEqual(
- (
- "Issue: 'Test issue' from B999:bandit_plugin: Severity: MEDIUM"
- " Confidence: MEDIUM at code.py:1"
- ),
- str(test_issue),
+ expect % str(issue.Cwe(issue.Cwe.MULTIPLE_BINDS)), str(test_issue)
)
def test_issue_as_dict(self):
@@ -108,7 +111,9 @@ def test_matches_issue(self):
@mock.patch("linecache.getline")
def test_get_code(self, getline):
getline.return_value = b"\x08\x30"
- new_issue = issue.Issue(bandit.MEDIUM, lineno=1)
+ new_issue = issue.Issue(
+ bandit.MEDIUM, cwe=issue.Cwe.MULTIPLE_BINDS, lineno=1
+ )
try:
new_issue.get_code()
@@ -116,8 +121,12 @@ def test_get_code(self, getline):
self.fail("Bytes not properly decoded in issue.get_code()")
-def _get_issue_instance(severity=bandit.MEDIUM, confidence=bandit.MEDIUM):
- new_issue = issue.Issue(severity, confidence, "Test issue")
+def _get_issue_instance(
+ severity=bandit.MEDIUM,
+ cwe=issue.Cwe.MULTIPLE_BINDS,
+ confidence=bandit.MEDIUM,
+):
+ new_issue = issue.Issue(severity, cwe, confidence, "Test issue")
new_issue.fname = "code.py"
new_issue.test = "bandit_plugin"
new_issue.test_id = "B999"
diff --git a/tests/unit/core/test_manager.py b/tests/unit/core/test_manager.py
index 616e6cc9c..b507d104c 100644
--- a/tests/unit/core/test_manager.py
+++ b/tests/unit/core/test_manager.py
@@ -15,8 +15,13 @@
class ManagerTests(testtools.TestCase):
- def _get_issue_instance(self, sev=constants.MEDIUM, conf=constants.MEDIUM):
- new_issue = issue.Issue(sev, conf, "Test issue")
+ def _get_issue_instance(
+ self,
+ sev=constants.MEDIUM,
+ cwe=issue.Cwe.MULTIPLE_BINDS,
+ conf=constants.MEDIUM,
+ ):
+ new_issue = issue.Issue(sev, cwe, conf, "Test issue")
new_issue.fname = "code.py"
new_issue.test = "bandit_plugin"
new_issue.lineno = 1
@@ -130,6 +135,10 @@ def test_populate_baseline_success(self):
"code": "test code",
"filename": "example_file.py",
"issue_severity": "low",
+ "issue_cwe": {
+ "id": 605,
+ "link": "%s"
+ },
"issue_confidence": "low",
"issue_text": "test issue",
"test_name": "some_test",
@@ -139,11 +148,14 @@ def test_populate_baseline_success(self):
}
]
}
- """
+ """ % (
+ "https://cwe.mitre.org/data/definitions/605.html"
+ )
issue_dictionary = {
"code": "test code",
"filename": "example_file.py",
"issue_severity": "low",
+ "issue_cwe": issue.Cwe(issue.Cwe.MULTIPLE_BINDS).as_dict(),
"issue_confidence": "low",
"issue_text": "test issue",
"test_name": "some_test",
@@ -167,7 +179,10 @@ def test_populate_baseline_invalid_json(self, mock_logger_warning):
def test_results_count(self):
levels = [constants.LOW, constants.MEDIUM, constants.HIGH]
self.manager.results = [
- issue.Issue(severity=level, confidence=level) for level in levels
+ issue.Issue(
+ severity=level, cwe=issue.Cwe.MULTIPLE_BINDS, confidence=level
+ )
+ for level in levels
]
r = [
diff --git a/tests/unit/formatters/test_csv.py b/tests/unit/formatters/test_csv.py
index 77dc9bc48..fd9166e30 100644
--- a/tests/unit/formatters/test_csv.py
+++ b/tests/unit/formatters/test_csv.py
@@ -26,7 +26,10 @@ def setUp(self):
}
self.check_name = "hardcoded_bind_all_interfaces"
self.issue = issue.Issue(
- bandit.MEDIUM, bandit.MEDIUM, "Possible binding to all interfaces."
+ bandit.MEDIUM,
+ 123,
+ bandit.MEDIUM,
+ "Possible binding to all interfaces.",
)
self.manager.out_file = self.tmp_fname
diff --git a/tests/unit/formatters/test_custom.py b/tests/unit/formatters/test_custom.py
index 16335d13f..908ddb3e7 100644
--- a/tests/unit/formatters/test_custom.py
+++ b/tests/unit/formatters/test_custom.py
@@ -25,7 +25,9 @@ def setUp(self):
}
self.check_name = "hardcoded_bind_all_interfaces"
self.issue = issue.Issue(
- bandit.MEDIUM, bandit.MEDIUM, "Possible binding to all interfaces."
+ bandit.MEDIUM,
+ bandit.MEDIUM,
+ text="Possible binding to all interfaces.",
)
self.manager.out_file = self.tmp_fname
diff --git a/tests/unit/formatters/test_html.py b/tests/unit/formatters/test_html.py
index f115e146d..07e6bd0b4 100644
--- a/tests/unit/formatters/test_html.py
+++ b/tests/unit/formatters/test_html.py
@@ -149,8 +149,10 @@ def test_escaping(self, get_issue_list, get_code):
self.assertNotIn(marker, contents)
-def _get_issue_instance(severity=bandit.MEDIUM, confidence=bandit.MEDIUM):
- new_issue = issue.Issue(severity, confidence, "Test issue")
+def _get_issue_instance(
+ severity=bandit.MEDIUM, cwe=123, confidence=bandit.MEDIUM
+):
+ new_issue = issue.Issue(severity, cwe, confidence, "Test issue")
new_issue.fname = "code.py"
new_issue.test = "bandit_plugin"
new_issue.lineno = 1
diff --git a/tests/unit/formatters/test_json.py b/tests/unit/formatters/test_json.py
index 454faa300..ddc1cde51 100644
--- a/tests/unit/formatters/test_json.py
+++ b/tests/unit/formatters/test_json.py
@@ -30,12 +30,27 @@ def setUp(self):
}
self.check_name = "hardcoded_bind_all_interfaces"
self.issue = issue.Issue(
- bandit.MEDIUM, bandit.MEDIUM, "Possible binding to all interfaces."
+ bandit.MEDIUM,
+ issue.Cwe.MULTIPLE_BINDS,
+ bandit.MEDIUM,
+ "Possible binding to all interfaces.",
)
self.candidates = [
- issue.Issue(bandit.LOW, bandit.LOW, "Candidate A", lineno=1),
- issue.Issue(bandit.HIGH, bandit.HIGH, "Candiate B", lineno=2),
+ issue.Issue(
+ issue.Cwe.MULTIPLE_BINDS,
+ bandit.LOW,
+ bandit.LOW,
+ "Candidate A",
+ lineno=1,
+ ),
+ issue.Issue(
+ bandit.HIGH,
+ issue.Cwe.MULTIPLE_BINDS,
+ bandit.HIGH,
+ "Candiate B",
+ lineno=2,
+ ),
]
self.manager.out_file = self.tmp_fname
diff --git a/tests/unit/formatters/test_screen.py b/tests/unit/formatters/test_screen.py
index cdeeeb34d..e2d420aed 100644
--- a/tests/unit/formatters/test_screen.py
+++ b/tests/unit/formatters/test_screen.py
@@ -35,9 +35,10 @@ def _template(_issue, _indent_val, _code, _color):
_issue.test,
_issue.text,
),
- "{} Severity: {} Confidence: {}".format(
+ "{} Severity: {} CWE: {} Confidence: {}".format(
_indent_val,
_issue.severity.capitalize(),
+ _issue.cwe,
_issue.confidence.capitalize(),
),
"{} Location: {}:{}:{}".format(
@@ -232,8 +233,10 @@ def test_report_baseline(self, get_issue_list):
output_str.assert_has_calls(calls, any_order=True)
-def _get_issue_instance(severity=bandit.MEDIUM, confidence=bandit.MEDIUM):
- new_issue = issue.Issue(severity, confidence, "Test issue")
+def _get_issue_instance(
+ severity=bandit.MEDIUM, cwe=123, confidence=bandit.MEDIUM
+):
+ new_issue = issue.Issue(severity, cwe, confidence, "Test issue")
new_issue.fname = "code.py"
new_issue.test = "bandit_plugin"
new_issue.lineno = 1
diff --git a/tests/unit/formatters/test_text.py b/tests/unit/formatters/test_text.py
index a55172d0b..2ce80d499 100644
--- a/tests/unit/formatters/test_text.py
+++ b/tests/unit/formatters/test_text.py
@@ -31,9 +31,10 @@ def _template(_issue, _indent_val, _code):
"{}>> Issue: [{}:{}] {}".format(
_indent_val, _issue.test_id, _issue.test, _issue.text
),
- "{} Severity: {} Confidence: {}".format(
+ "{} Severity: {} CWE: {} Confidence: {}".format(
_indent_val,
_issue.severity.capitalize(),
+ _issue.cwe,
_issue.confidence.capitalize(),
),
"{} Location: {}:{}:{}".format(
@@ -143,6 +144,7 @@ def test_report_nobaseline(self, get_issue_list):
"binding.py (score: ",
"CONFIDENCE: 1",
"SEVERITY: 1",
+ "CWE: %s" % str(issue.Cwe(issue.Cwe.MULTIPLE_BINDS)),
"Files excluded (1):",
"def.py",
"Undefined: 1",
@@ -202,8 +204,12 @@ def test_report_baseline(self, get_issue_list):
output_str.assert_has_calls(calls, any_order=True)
-def _get_issue_instance(severity=bandit.MEDIUM, confidence=bandit.MEDIUM):
- new_issue = issue.Issue(severity, confidence, "Test issue")
+def _get_issue_instance(
+ severity=bandit.MEDIUM,
+ cwe=issue.Cwe.MULTIPLE_BINDS,
+ confidence=bandit.MEDIUM,
+):
+ new_issue = issue.Issue(severity, cwe, confidence, "Test issue")
new_issue.fname = "code.py"
new_issue.test = "bandit_plugin"
new_issue.lineno = 1
diff --git a/tests/unit/formatters/test_xml.py b/tests/unit/formatters/test_xml.py
index c2c06d3f6..64e271882 100644
--- a/tests/unit/formatters/test_xml.py
+++ b/tests/unit/formatters/test_xml.py
@@ -27,7 +27,10 @@ def setUp(self):
}
self.check_name = "hardcoded_bind_all_interfaces"
self.issue = issue.Issue(
- bandit.MEDIUM, bandit.MEDIUM, "Possible binding to all interfaces."
+ bandit.MEDIUM,
+ issue.Cwe.MULTIPLE_BINDS,
+ bandit.MEDIUM,
+ "Possible binding to all interfaces.",
)
self.manager.out_file = self.tmp_fname
diff --git a/tests/unit/formatters/test_yaml.py b/tests/unit/formatters/test_yaml.py
index bca249c78..30df3851d 100644
--- a/tests/unit/formatters/test_yaml.py
+++ b/tests/unit/formatters/test_yaml.py
@@ -30,12 +30,15 @@ def setUp(self):
}
self.check_name = "hardcoded_bind_all_interfaces"
self.issue = issue.Issue(
- bandit.MEDIUM, bandit.MEDIUM, "Possible binding to all interfaces."
+ bandit.MEDIUM,
+ 123,
+ bandit.MEDIUM,
+ "Possible binding to all interfaces.",
)
self.candidates = [
- issue.Issue(bandit.LOW, bandit.LOW, "Candidate A", lineno=1),
- issue.Issue(bandit.HIGH, bandit.HIGH, "Candiate B", lineno=2),
+ issue.Issue(bandit.LOW, 123, bandit.LOW, "Candidate A", lineno=1),
+ issue.Issue(bandit.HIGH, 123, bandit.HIGH, "Candiate B", lineno=2),
]
self.manager.out_file = self.tmp_fname