Skip to content

Commit

Permalink
Included CWE information
Browse files Browse the repository at this point in the history
  • Loading branch information
julianthome committed May 13, 2020
1 parent 59cd94e commit 7304106
Show file tree
Hide file tree
Showing 36 changed files with 79 additions and 33 deletions.
2 changes: 1 addition & 1 deletion bandit/core/blacklisting.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

def report_issue(check, name):
return issue.Issue(
severity=check.get('level', 'MEDIUM'), confidence='HIGH',
severity=check.get('level', 'MEDIUM'), cwe=0, confidence='HIGH',
text=check['message'].replace('{name}', name),
ident=name, test_id=check.get("id", 'LEGACY'))

Expand Down
21 changes: 13 additions & 8 deletions bandit/core/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@


class Issue(object):
def __init__(self, severity, confidence=constants.CONFIDENCE_DEFAULT,
def __init__(self, severity, cwe,
confidence=constants.CONFIDENCE_DEFAULT,
text="", ident=None, lineno=None, test_id=""):
self.severity = severity
self.cwe = cwe
self.confidence = confidence
if isinstance(text, bytes):
text = text.decode('utf-8')
Expand All @@ -30,16 +32,17 @@ def __init__(self, severity, confidence=constants.CONFIDENCE_DEFAULT,
self.linerange = []

def __str__(self):
return ("Issue: '%s' from %s:%s: Severity: %s Confidence: "
return ("Issue: '%s' from %s:%s: CWE: %i, Severity: %s Confidence: "
"%s at %s:%i") % (self.text, self.test_id,
(self.ident or self.test), self.severity,
self.confidence, self.fname, self.lineno)
(self.ident or self.test), self.cwe,
self.severity, self.confidence, self.fname,
self.lineno)

def __eq__(self, other):
# if the issue text, severity, confidence, and filename match, it's
# the same issue from our perspective
match_types = ['text', 'severity', 'confidence', 'fname', 'test',
'test_id']
match_types = ['text', 'severity', 'cwe', 'confidence', 'fname',
'test', 'test_id']
return all(getattr(self, field) == getattr(other, field)
for field in match_types)

Expand Down Expand Up @@ -101,11 +104,12 @@ def as_dict(self, with_code=True):
'test_name': self.test,
'test_id': self.test_id,
'issue_severity': self.severity,
'issue_cwe': self.cwe,
'issue_confidence': self.confidence,
'issue_text': self.text.encode('utf-8').decode('utf-8'),
'line_number': self.lineno,
'line_range': self.linerange,
}
}

if with_code:
out['code'] = self.get_code()
Expand All @@ -115,6 +119,7 @@ def from_dict(self, data, with_code=True):
self.code = data["code"]
self.fname = data["filename"]
self.severity = data["issue_severity"]
self.cwe = int(data["issue_cwe"])
self.confidence = data["issue_confidence"]
self.text = data["issue_text"]
self.test = data["test_name"]
Expand All @@ -124,6 +129,6 @@ def from_dict(self, data, with_code=True):


def issue_from_dict(data):
i = Issue(severity=data["issue_severity"])
i = Issue(severity=data["issue_severity"], cwe=int(data["issue_cwe"]))
i.from_dict(data)
return i
1 change: 1 addition & 0 deletions bandit/plugins/app_debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def flask_debug_true(context):
if context.check_call_arg_value('debug', 'True'):
return bandit.Issue(
severity=bandit.HIGH,
cwe=94,
confidence=bandit.MEDIUM,
text="A Flask app appears to be run with debug=True, "
"which exposes the Werkzeug debugger and allows "
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
def assert_used(context):
return bandit.Issue(
severity=bandit.LOW,
cwe=703,
confidence=bandit.HIGH,
text=("Use of assert detected. The enclosed code "
"will be removed when compiling to optimised byte code.")
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/crypto_request_no_cert_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,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=295,
confidence=bandit.HIGH,
text="Requests call with verify=False disabling SSL "
"certificate checks, security issue.",
Expand Down
2 changes: 2 additions & 0 deletions bandit/plugins/django_sql_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def django_extra_used(context):
if insecure:
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=89,
confidence=bandit.MEDIUM,
text=description
)
Expand All @@ -102,6 +103,7 @@ def django_rawsql_used(context):
if not isinstance(sql, ast.Str):
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=89,
confidence=bandit.MEDIUM,
text=description
)
1 change: 1 addition & 0 deletions bandit/plugins/django_xss.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ def check_risk(node):
if not secure:
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=80,
confidence=bandit.HIGH,
text=description
)
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
def exec_issue():
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=78,
confidence=bandit.HIGH,
text="Use of exec detected."
)
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/general_bad_file_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def set_bad_file_permissions(context):
filename = 'NOT PARSED'
return bandit.Issue(
severity=sev_level,
cwe=78,
confidence=bandit.HIGH,
text="Chmod setting a permissive mask %s on file (%s)." %
(oct(mode), filename)
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/general_bind_all_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def hardcoded_bind_all_interfaces(context):
if context.string_val == '0.0.0.0':
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=605,
confidence=bandit.MEDIUM,
text="Possible binding to all interfaces."
)
1 change: 1 addition & 0 deletions bandit/plugins/general_hardcoded_password.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
def _report(value):
return bandit.Issue(
severity=bandit.LOW,
cwe=259,
confidence=bandit.MEDIUM,
text=("Possible hardcoded password: '%s'" % value))

Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/general_hardcoded_tmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,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=377,
confidence=bandit.MEDIUM,
text="Probable insecure usage of temp file/directory."
)
1 change: 1 addition & 0 deletions bandit/plugins/hashlib_new_insecure_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def hashlib_new(context):
name.lower() in ('md4', 'md5', 'sha', 'sha1')):
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=327,
confidence=bandit.HIGH,
text="Use of insecure MD4 or MD5 hash function.",
lineno=context.node.lineno,
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/injection_paramiko.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ def paramiko_calls(context):
if context.is_module_imported_like(module):
if context.call_function_name in ['exec_command']:
return bandit.Issue(severity=bandit.MEDIUM,
cwe=78,
confidence=bandit.MEDIUM,
text=issue_text)
8 changes: 8 additions & 0 deletions bandit/plugins/injection_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ def subprocess_popen_with_shell_equals_true(context, config):
if sev == bandit.LOW:
return bandit.Issue(
severity=bandit.LOW,
cwe=78,
confidence=bandit.HIGH,
text='subprocess call with shell=True seems safe, but '
'may be changed in the future, consider '
Expand All @@ -208,6 +209,7 @@ def subprocess_popen_with_shell_equals_true(context, config):
else:
return bandit.Issue(
severity=bandit.HIGH,
cwe=78,
confidence=bandit.HIGH,
text='subprocess call with shell=True identified, '
'security issue.',
Expand Down Expand Up @@ -287,6 +289,7 @@ def subprocess_without_shell_equals_true(context, config):
if not has_shell(context):
return bandit.Issue(
severity=bandit.LOW,
cwe=78,
confidence=bandit.HIGH,
text='subprocess call - check for execution of untrusted '
'input.',
Expand Down Expand Up @@ -365,6 +368,7 @@ def any_other_function_with_shell_equals_true(context, config):
if has_shell(context):
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=78,
confidence=bandit.LOW,
text='Function call with shell=True parameter identified, '
'possible security issue.',
Expand Down Expand Up @@ -451,6 +455,7 @@ def start_process_with_a_shell(context, config):
if sev == bandit.LOW:
return bandit.Issue(
severity=bandit.LOW,
cwe=78,
confidence=bandit.HIGH,
text='Starting a process with a shell: '
'Seems safe, but may be changed in the future, '
Expand All @@ -459,6 +464,7 @@ def start_process_with_a_shell(context, config):
else:
return bandit.Issue(
severity=bandit.HIGH,
cwe=78,
confidence=bandit.HIGH,
text='Starting a process with a shell, possible injection'
' detected, security issue.'
Expand Down Expand Up @@ -547,6 +553,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=78,
confidence=bandit.MEDIUM,
text='Starting a process without a shell.'
)
Expand Down Expand Up @@ -642,6 +649,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=78,
confidence=bandit.HIGH,
text='Starting a process with a partial executable path'
)
1 change: 1 addition & 0 deletions bandit/plugins/injection_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def hardcoded_sql_expressions(context):
if _check_string(val[1]):
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=89,
confidence=bandit.MEDIUM if val[0] else bandit.LOW,
text="Possible SQL injection vector through string-based "
"query construction."
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/injection_wildcard.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ def linux_commands_wildcard_injection(context, config):
):
return bandit.Issue(
severity=bandit.HIGH,
cwe=155,
confidence=bandit.MEDIUM,
text="Possible wildcard injection in call: %s" %
context.call_function_name_qual,
Expand Down
5 changes: 5 additions & 0 deletions bandit/plugins/insecure_ssl_tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,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=326,
confidence=bandit.HIGH,
text="ssl.wrap_socket call with insecure SSL/TLS protocol "
"version identified, security issue.",
Expand All @@ -114,6 +115,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=326,
confidence=bandit.HIGH,
text="SSL.Context call with insecure SSL/TLS protocol "
"version identified, security issue.",
Expand All @@ -128,6 +130,7 @@ def ssl_with_bad_version(context, config):
context.get_lineno_for_call_arg('ssl_version'))
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=326,
confidence=bandit.MEDIUM,
text="Function call with insecure SSL/TLS protocol "
"identified, possible security issue.",
Expand Down Expand Up @@ -186,6 +189,7 @@ def ssl_with_bad_defaults(context, config):
if val in bad_ssl_versions:
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=326,
confidence=bandit.MEDIUM,
text="Function definition identified with insecure SSL/TLS "
"protocol version by default, possible security "
Expand Down Expand Up @@ -245,6 +249,7 @@ def ssl_with_no_version(context):
# tests for that (ssl_version is not specified).
return bandit.Issue(
severity=bandit.LOW,
cwe=326,
confidence=bandit.MEDIUM,
text="ssl.wrap_socket call with no SSL/TLS protocol version "
"specified, the default SSLv23 could be insecure, "
Expand Down
3 changes: 3 additions & 0 deletions bandit/plugins/jinja2_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def jinja2_autoescape_false(context):
getattr(node.value, 'value', None) is False)):
return bandit.Issue(
severity=bandit.HIGH,
cwe=94,
confidence=bandit.HIGH,
text="Using jinja2 templates with autoescape="
"False is dangerous and can lead to XSS. "
Expand All @@ -103,6 +104,7 @@ def jinja2_autoescape_false(context):
else:
return bandit.Issue(
severity=bandit.HIGH,
cwe=94,
confidence=bandit.MEDIUM,
text="Using jinja2 templates with autoescape="
"False is dangerous and can lead to XSS. "
Expand All @@ -114,6 +116,7 @@ def jinja2_autoescape_false(context):
# behavior
return bandit.Issue(
severity=bandit.HIGH,
cwe=94,
confidence=bandit.HIGH,
text="By default, jinja2 sets autoescape to False. Consider "
"using autoescape=True or use the select_autoescape "
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/mako_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def use_of_mako_templates(context):
# feature and thus each variable must be carefully sanitized.
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=94,
confidence=bandit.HIGH,
text="Mako templates allow HTML/JS rendering by default and "
"are inherently open to XSS attacks. Ensure variables "
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/ssh_no_host_key_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def ssh_no_host_key_verification(context):
context.call_args[0] in ['AutoAddPolicy', 'WarningPolicy']):
issue = bandit.Issue(
severity=bandit.HIGH,
cwe=295,
confidence=bandit.MEDIUM,
text='Paramiko call with policy set to automatically trust '
'the unknown host key.',
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/try_except_continue.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,6 @@ def try_except_continue(context, config):
if isinstance(node.body[0], ast.Continue):
return bandit.Issue(
severity=bandit.LOW,
cwe=703,
confidence=bandit.HIGH,
text=("Try, Except, Continue detected."))
1 change: 1 addition & 0 deletions bandit/plugins/try_except_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def try_except_pass(context, config):
if isinstance(node.body[0], ast.Pass):
return bandit.Issue(
severity=bandit.LOW,
cwe=703,
confidence=bandit.HIGH,
text=("Try, Except, Pass detected.")
)
1 change: 1 addition & 0 deletions bandit/plugins/weak_cryptographic_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def _classify_key_size(config, key_type, key_size):
if key_size < size:
return bandit.Issue(
severity=level,
cwe=326,
confidence=bandit.HIGH,
text='%s key sizes below %d bits are considered breakable. ' %
(key_type, size))
Expand Down
1 change: 1 addition & 0 deletions bandit/plugins/yaml_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def yaml_load(context):
]):
return bandit.Issue(
severity=bandit.MEDIUM,
cwe=20,
confidence=bandit.HIGH,
text="Use of unsafe yaml load. Allows instantiation of"
" arbitrary objects. Consider yaml.safe_load().",
Expand Down
1 change: 1 addition & 0 deletions tests/functional/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ def test_baseline_filter(self):
"filename": "%s/examples/flask_debug.py",
"issue_confidence": "MEDIUM",
"issue_severity": "HIGH",
"issue_cwe": "94",
"issue_text": "%s",
"line_number": 10,
"line_range": [
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/core/test_blacklisting.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,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(0, issue_dict['issue_cwe'])
self.assertEqual('HIGH', issue_dict['issue_confidence'])
self.assertEqual('test name', issue_dict['issue_text'])

Expand All @@ -29,5 +30,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(0, issue_dict['issue_cwe'])
self.assertEqual('HIGH', issue_dict['issue_confidence'])
self.assertEqual('test name', issue_dict['issue_text'])

0 comments on commit 7304106

Please sign in to comment.