diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py
index bc8689396..4f6d51050 100644
--- a/tests/functional/test_functional.py
+++ b/tests/functional/test_functional.py
@@ -98,104 +98,6 @@ def check_metrics(self, example_script, expect):
expected = expect["issues"][criteria][rank]
self.assertEqual(expected, m["_totals"][label])
- def test_binding(self):
- """Test the bind-to-0.0.0.0 example."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- }
- self.check_example("binding.py", expect)
-
- def test_crypto_md5(self):
- """Test the `hashlib.md5` example."""
- if sys.version_info >= (3, 9):
- expect = {
- "SEVERITY": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 10,
- "HIGH": 9,
- },
- "CONFIDENCE": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 0,
- "HIGH": 19,
- },
- }
- else:
- expect = {
- "SEVERITY": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 16,
- "HIGH": 4,
- },
- "CONFIDENCE": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 0,
- "HIGH": 20,
- },
- }
- self.check_example("crypto-md5.py", expect)
-
- def test_ciphers(self):
- """Test the `Crypto.Cipher` example."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 21},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 22},
- }
- self.check_example("ciphers.py", expect)
-
- def test_cipher_modes(self):
- """Test for insecure cipher modes."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 1},
- }
- self.check_example("cipher-modes.py", expect)
-
- def test_eval(self):
- """Test the `eval` example."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 3, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 3},
- }
- self.check_example("eval.py", expect)
-
- def test_mark_safe(self):
- """Test the `mark_safe` example."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 1},
- }
- self.check_example("mark_safe.py", expect)
-
- def test_exec(self):
- """Test the `exec` example."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 1},
- }
- self.check_example("exec.py", expect)
-
- def test_hardcoded_passwords(self):
- """Test for hard-coded passwords."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 14, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 14, "HIGH": 0},
- }
- self.check_example("hardcoded-passwords.py", expect)
-
- def test_hardcoded_tmp(self):
- """Test for hard-coded /tmp, /var/tmp, /dev/shm."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 3, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 3, "HIGH": 0},
- }
- self.check_example("hardcoded-tmp.py", expect)
-
def test_imports_aliases(self):
"""Test the `import X as Y` syntax."""
if sys.version_info >= (3, 9):
@@ -236,22 +138,6 @@ def test_imports_function(self):
}
self.check_example("imports-function.py", expect)
- def test_telnet_usage(self):
- """Test for `import telnetlib` and Telnet.* calls."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- }
- self.check_example("telnetlib.py", expect)
-
- def test_ftp_usage(self):
- """Test for `import ftplib` and FTP.* calls."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- }
- self.check_example("ftplib.py", expect)
-
def test_imports(self):
"""Test for dangerous imports."""
expect = {
@@ -268,14 +154,6 @@ def test_imports_using_importlib(self):
}
self.check_example("imports-with-importlib.py", expect)
- def test_mktemp(self):
- """Test for `tempfile.mktemp`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 4, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 4},
- }
- self.check_example("mktemp.py", expect)
-
def test_nonsense(self):
"""Test that a syntactically invalid module is skipped."""
self.run_example("nonsense.py")
@@ -297,126 +175,6 @@ def test_subdirectory_okay(self):
}
self.check_example("init-py-test/subdirectory-okay.py", expect)
- def test_os_chmod(self):
- """Test setting file permissions."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 4, "HIGH": 8},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 11},
- }
- self.check_example("os-chmod.py", expect)
-
- def test_os_exec(self):
- """Test for `os.exec*`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 8, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 8, "HIGH": 0},
- }
- self.check_example("os-exec.py", expect)
-
- def test_os_popen(self):
- """Test for `os.popen`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 8, "MEDIUM": 0, "HIGH": 1},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 9},
- }
- self.check_example("os-popen.py", expect)
-
- def test_os_spawn(self):
- """Test for `os.spawn*`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 8, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 8, "HIGH": 0},
- }
- self.check_example("os-spawn.py", expect)
-
- def test_os_startfile(self):
- """Test for `os.startfile`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 3, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 3, "HIGH": 0},
- }
- self.check_example("os-startfile.py", expect)
-
- def test_os_system(self):
- """Test for `os.system`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 1},
- }
- self.check_example("os_system.py", expect)
-
- def test_pickle(self):
- """Test for the `pickle` module."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 3, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 4},
- }
- self.check_example("pickle_deserialize.py", expect)
-
- def test_dill(self):
- """Test for the `dill` module."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 3, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 4},
- }
- self.check_example("dill.py", expect)
-
- def test_shelve(self):
- """Test for the `shelve` module."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 2, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 3},
- }
- self.check_example("shelve_open.py", expect)
-
- def test_jsonpickle(self):
- """Test for the `jsonpickle` module."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 3, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 3},
- }
- self.check_example("jsonpickle.py", expect)
-
- def test_pandas_read_pickle(self):
- """Test for the `pandas.read_pickle` module."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 1, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- }
- self.check_example("pandas_read_pickle.py", expect)
-
- def test_popen_wrappers(self):
- """Test the `popen2` and `commands` modules."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 7, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 7},
- }
- self.check_example("popen_wrappers.py", expect)
-
- def test_random_module(self):
- """Test for the `random` module."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 7, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 7},
- }
- self.check_example("random_module.py", expect)
-
- def test_requests_ssl_verify_disabled(self):
- """Test for the `requests` library skipping verification."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 18},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 18},
- }
- self.check_example("requests-ssl-verify-disabled.py", expect)
-
- def test_requests_without_timeout(self):
- """Test for the `requests` library missing timeouts."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 14, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 14, "MEDIUM": 0, "HIGH": 0},
- }
- self.check_example("requests-missing-timeout.py", expect)
-
def test_skip(self):
"""Test `#nosec` and `#noqa` comments."""
expect = {
@@ -433,24 +191,6 @@ def test_ignore_skip(self):
}
self.check_example("skip.py", expect, ignore_nosec=True)
- def test_sql_statements(self):
- """Test for SQL injection through string building."""
- expect = {
- "SEVERITY": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 18,
- "HIGH": 0,
- },
- "CONFIDENCE": {
- "UNDEFINED": 0,
- "LOW": 8,
- "MEDIUM": 10,
- "HIGH": 0,
- },
- }
- self.check_example("sql_statements.py", expect)
-
def test_multiline_sql_statements(self):
"""
Test for SQL injection through string building using
@@ -494,110 +234,6 @@ def test_multiline_sql_statements(self):
self.check_example(example_file, expect)
self.check_metrics(example_file, expect_stats)
- def test_ssl_insecure_version(self):
- """Test for insecure SSL protocol versions."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 13, "HIGH": 9},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 14, "HIGH": 9},
- }
- self.check_example("ssl-insecure-version.py", expect)
-
- def test_subprocess_shell(self):
- """Test for `subprocess.Popen` with `shell=True`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 21, "MEDIUM": 1, "HIGH": 11},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 0, "HIGH": 32},
- }
- self.check_example("subprocess_shell.py", expect)
-
- def test_urlopen(self):
- """Test for dangerous URL opening."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 8, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 8},
- }
- self.check_example("urlopen.py", expect)
-
- def test_wildcard_injection(self):
- """Test for wildcard injection in shell commands."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 10, "MEDIUM": 0, "HIGH": 4},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 5, "HIGH": 9},
- }
- self.check_example("wildcard-injection.py", expect)
-
- def test_django_sql_injection(self):
- """Test insecure extra functions on Django."""
-
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 11, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 11, "HIGH": 0},
- }
- self.check_example("django_sql_injection_extra.py", expect)
-
- def test_django_sql_injection_raw(self):
- """Test insecure raw functions on Django."""
-
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 4, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 4, "HIGH": 0},
- }
- self.check_example("django_sql_injection_raw.py", expect)
-
- def test_yaml(self):
- """Test for `yaml.load`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 2, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- }
- self.check_example("yaml_load.py", expect)
-
- def test_host_key_verification(self):
- """Test for ignoring host key verification."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 2, "HIGH": 0},
- }
- self.check_example("no_host_key_verification.py", expect)
-
- def test_jinja2_templating(self):
- """Test jinja templating for potential XSS bugs."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 5},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 2, "HIGH": 3},
- }
- self.check_example("jinja2_templating.py", expect)
-
- def test_mako_templating(self):
- """Test Mako templates for XSS."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 3, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 3},
- }
- self.check_example("mako_templating.py", expect)
-
- def test_django_xss_secure(self):
- """Test false positives for Django XSS"""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 0},
- }
- self.b_mgr.b_ts = b_test_set.BanditTestSet(
- config=self.b_mgr.b_conf, profile={"exclude": ["B308"]}
- )
- self.check_example("mark_safe_secure.py", expect)
-
- def test_django_xss_insecure(self):
- """Test for Django XSS via django.utils.safestring"""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 29, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 29},
- }
- self.b_mgr.b_ts = b_test_set.BanditTestSet(
- config=self.b_mgr.b_conf, profile={"exclude": ["B308"]}
- )
- self.check_example("mark_safe_insecure.py", expect)
-
def test_xml(self):
"""Test xml vulnerabilities."""
expect = {
@@ -654,17 +290,7 @@ def test_xml(self):
}
self.check_example("xml_sax.py", expect)
- def test_httpoxy(self):
- """Test httpoxy vulnerability."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 1},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 1},
- }
- self.check_example("httpoxy_cgihandler.py", expect)
- self.check_example("httpoxy_twisted_script.py", expect)
- self.check_example("httpoxy_twisted_directory.py", expect)
-
- def test_asserts(self):
+ def test_skips(self):
"""Test catching the use of assert."""
test = next(
x
@@ -693,66 +319,6 @@ def test_asserts(self):
}
self.check_example("assert.py", expect)
- def test_paramiko_injection(self):
- """Test paramiko command execution."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- }
- self.check_example("paramiko_injection.py", expect)
-
- def test_partial_path(self):
- """Test process spawning with partial file paths."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 11, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 11},
- }
- self.check_example("partial_path_process.py", expect)
-
- def test_try_except_continue(self):
- """Test try, except, continue detection."""
- test = next(
- x
- for x in self.b_mgr.b_ts.tests["ExceptHandler"]
- if x.__name__ == "try_except_continue"
- )
-
- test._config = {"check_typed_exception": True}
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 3, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 3},
- }
- self.check_example("try_except_continue.py", expect)
-
- test._config = {"check_typed_exception": False}
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 2, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- }
- self.check_example("try_except_continue.py", expect)
-
- def test_try_except_pass(self):
- """Test try, except pass detection."""
- test = next(
- x
- for x in self.b_mgr.b_ts.tests["ExceptHandler"]
- if x.__name__ == "try_except_pass"
- )
-
- test._config = {"check_typed_exception": True}
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 3, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 3},
- }
- self.check_example("try_except_pass.py", expect)
-
- test._config = {"check_typed_exception": False}
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 2, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- }
- self.check_example("try_except_pass.py", expect)
-
def test_metric_gathering(self):
expect = {
"nosec": 2,
@@ -767,14 +333,6 @@ def test_metric_gathering(self):
}
self.check_metrics("imports.py", expect)
- def test_weak_cryptographic_key(self):
- """Test for weak key sizes."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 8, "HIGH": 8},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 16},
- }
- self.check_example("weak_cryptographic_key_sizes.py", expect)
-
def test_multiline_code(self):
"""Test issues in multiline statements return code as expected."""
self.run_example("multiline_statement.py")
@@ -815,13 +373,6 @@ def test_code_line_numbers(self):
self.assertEqual("%i " % (lineno), code_lines[1][:2])
self.assertEqual("%i " % (lineno + 1), code_lines[2][:2])
- def test_flask_debug_true(self):
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 1},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- }
- self.check_example("flask_debug.py", expect)
-
def test_nosec(self):
expect = {
"SEVERITY": {"UNDEFINED": 0, "LOW": 5, "MEDIUM": 0, "HIGH": 0},
@@ -863,88 +414,3 @@ def test_baseline_filter(self):
self.run_example("flask_debug.py")
self.assertEqual(1, len(self.b_mgr.baseline))
self.assertEqual({}, self.b_mgr.get_issue_list())
-
- def test_unverified_context(self):
- """Test for `ssl._create_unverified_context`."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 1},
- }
- self.check_example("unverified_context.py", expect)
-
- def test_hashlib_new_insecure_functions(self):
- """Test insecure hash functions created by `hashlib.new`."""
- if sys.version_info >= (3, 9):
- expect = {
- "SEVERITY": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 0,
- "HIGH": 9,
- },
- "CONFIDENCE": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 0,
- "HIGH": 9,
- },
- }
- else:
- expect = {
- "SEVERITY": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 10,
- "HIGH": 0,
- },
- "CONFIDENCE": {
- "UNDEFINED": 0,
- "LOW": 0,
- "MEDIUM": 0,
- "HIGH": 10,
- },
- }
- self.check_example("hashlib_new_insecure_functions.py", expect)
-
- def test_blacklist_pycrypto(self):
- """Test importing pycrypto module"""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 2},
- }
- self.check_example("pycrypto.py", expect)
-
- def test_no_blacklist_pycryptodome(self):
- """Test importing pycryptodome module
-
- make sure it's no longer blacklisted
- """
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 0},
- }
- self.check_example("pycryptodome.py", expect)
-
- def test_blacklist_pyghmi(self):
- """Test calling pyghmi methods"""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 0, "HIGH": 1},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 1},
- }
- self.check_example("pyghmi.py", expect)
-
- def test_snmp_security_check(self):
- """Test insecure and weak crypto usage of SNMP."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 3, "HIGH": 0},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 0, "HIGH": 3},
- }
- self.check_example("snmp.py", expect)
-
- def test_tarfile_unsafe_members(self):
- """Test insecure usage of tarfile."""
- expect = {
- "SEVERITY": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 2, "HIGH": 1},
- "CONFIDENCE": {"UNDEFINED": 0, "LOW": 1, "MEDIUM": 2, "HIGH": 1},
- }
- self.check_example("tarfile_extractall.py", expect)
diff --git a/tests/unit/blacklists/base_test_case.py b/tests/unit/blacklists/base_test_case.py
new file mode 100644
index 000000000..536b7906e
--- /dev/null
+++ b/tests/unit/blacklists/base_test_case.py
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: Apache-2.0
+import testtools
+
+from bandit.core import config
+from bandit.core import manager
+from bandit.core import meta_ast
+from bandit.core import metrics
+from bandit.core import node_visitor
+from bandit.core import test_set
+
+
+class BaseTestCase(testtools.TestCase):
+ def setUp(self, test_ids):
+ super().setUp()
+ self.b_config = config.BanditConfig()
+ self.b_manager = manager.BanditManager(self.b_config, "file")
+ issue_metrics = metrics.Metrics()
+ issue_metrics.begin("test.py")
+ self.visitor = node_visitor.BanditNodeVisitor(
+ "test.py",
+ None,
+ metaast=meta_ast.BanditMetaAst(),
+ testset=test_set.BanditTestSet(
+ self.b_config,
+ profile={
+ "include": test_ids,
+ "exclude": [],
+ },
+ ),
+ debug=False,
+ nosec_lines={},
+ metrics=issue_metrics,
+ )
diff --git a/tests/unit/blacklists/test_cipher_call.py b/tests/unit/blacklists/test_cipher_call.py
new file mode 100644
index 000000000..58a4474a5
--- /dev/null
+++ b/tests/unit/blacklists/test_cipher_call.py
@@ -0,0 +1,297 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class CipherCallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B304"])
+
+ def test_crypto_cipher_arc2_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Cipher import ARC2 as pycrypto_arc2
+ from Crypto import Random
+ key = b'Sixteen byte key'
+ iv = Random.new().read(pycrypto_arc2.block_size)
+ pycrypto_arc2.new(key, pycrypto_arc2.MODE_CFB, iv)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_crypto_cipher_arc4_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Cipher import ARC4 as pycrypto_arc4
+ from Crypto import Random
+ key = b'Very long and confidential key'
+ nonce = Random.new().read(16)
+ tempkey = SHA.new(key+nonce).digest()
+ pycrypto_arc4.new(tempkey)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_crypto_cipher_blowfish_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Cipher import Blowfish as pycrypto_blowfish
+ from Crypto import Random
+ key = b'An arbitrarily long key'
+ bs = pycrypto_blowfish.block_size
+ iv = Random.new().read(bs)
+ pycrypto_blowfish.new(key, pycrypto_blowfish.MODE_CBC, iv)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_crypto_cipher_des_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Cipher import DES as pycrypto_des
+ from Crypto import Random
+ nonce = Random.new().read(pycrypto_des.block_size / 2)
+ ctr = Counter.new(pycrypto_des.block_size * 8 / 2, prefix=nonce)
+ pycrypto_des.new(key, pycrypto_des.MODE_CTR, counter=ctr)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_crypto_cipher_xor_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Cipher import XOR as pycrypto_xor
+ key = b'Super secret key'
+ pycrypto_xor.new(key)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_cipher_arc2_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Cipher import ARC2 as pycryptodomex_arc2
+ from Crypto import Random
+ key = b'Sixteen byte key'
+ iv = Random.new().read(pycryptodomex_arc2.block_size)
+ pycryptodomex_arc2.new(key, pycryptodomex_arc2.MODE_CFB, iv)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_cipher_arc4_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Cipher import ARC4 as pycryptodomex_arc4
+ from Cryptodome import Random
+ key = b'Very long and confidential key'
+ nonce = Random.new().read(16)
+ tempkey = SHA.new(key + nonce).digest()
+ pycryptodomex_arc4.new(tempkey)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_cipher_blowfish_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Cipher import Blowfish as pycryptodomex_blowfish
+ from Cryptodome import Random
+ key = b'An arbitrarily long key'
+ bs = pycryptodomex_blowfish.block_size
+ iv = Random.new().read(bs)
+ mode = pycryptodomex_blowfish.MODE_CBC
+ pycryptodomex_blowfish.new(key, mode, iv)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(8, issue.lineno)
+ self.assertEqual([8], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_cipher_des_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Cipher import DES as pycryptodomex_des
+ from Cryptodome import Random
+ nonce = Random.new().read(pycryptodomex_des.block_size / 2)
+ ctr = Counter.new(pycryptodomex_des.block_size * 8/2, prefix=nonce)
+ pycryptodomex_des.new(key, pycryptodomex_des.MODE_CTR, counter=ctr)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_cipher_xor_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Cipher import XOR as pycryptodomex_xor
+ key = b'Super secret key'
+ pycryptodomex_xor.new(key)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptography_ciphers_algorithms_arc4(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat.primitives.ciphers import Cipher
+ from cryptography.hazmat.primitives.ciphers import algorithms
+ from cryptography.hazmat.backends import default_backend
+ key = b'Super secret key'
+ Cipher(
+ algorithms.ARC4(key),
+ mode=None,
+ backend=default_backend()
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_cryptography_ciphers_algorithms_blowfish(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat.primitives.ciphers import Cipher
+ from cryptography.hazmat.primitives.ciphers import algorithms
+ from cryptography.hazmat.backends import default_backend
+ key = b'Super secret key'
+ Cipher(
+ algorithms.Blowfish(key),
+ mode=None,
+ backend=default_backend()
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_cryptography_ciphers_algorithms_idea(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat.primitives.ciphers import Cipher
+ from cryptography.hazmat.primitives.ciphers import algorithms
+ from cryptography.hazmat.backends import default_backend
+ key = b'Super secret key'
+ Cipher(
+ algorithms.IDEA(key),
+ mode=None,
+ backend=default_backend(),
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B304", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
diff --git a/tests/unit/blacklists/test_cipher_modes.py b/tests/unit/blacklists/test_cipher_modes.py
new file mode 100644
index 000000000..27adfd2c0
--- /dev/null
+++ b/tests/unit/blacklists/test_cipher_modes.py
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class CipherModesTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B305"])
+
+ def test_cipher_mode_ecb(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ from cryptography.hazmat.primitives.ciphers.modes import ECB
+ iv = os.urandom(16)
+ ECB(iv)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B305", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cipher_mode_ctr(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ from cryptography.hazmat.primitives.ciphers import algorithms
+ from cryptography.hazmat.primitives.ciphers import modes
+ key = os.urandom(32)
+ iv = os.urandom(16)
+ algorithms.AES.new(key, modes.CTR, iv)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_cipher_mode_cbc(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ from cryptography.hazmat.primitives.ciphers.modes import CBC
+ iv = os.urandom(16)
+ CBC(iv)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/blacklists/test_eval_call.py b/tests/unit/blacklists/test_eval_call.py
new file mode 100644
index 000000000..19a27c7d3
--- /dev/null
+++ b/tests/unit/blacklists/test_eval_call.py
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class EvalCallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B307"])
+
+ def test_eval_call(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ eval("os.getcwd()")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B307", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_eval_method(self):
+ fdata = textwrap.dedent(
+ """
+ class Test(object):
+ def eval(self):
+ print("hi")
+ def foo(self):
+ self.eval()
+
+ Test().eval()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/blacklists/test_ftplib_call.py b/tests/unit/blacklists/test_ftplib_call.py
new file mode 100644
index 000000000..4444cbffe
--- /dev/null
+++ b/tests/unit/blacklists/test_ftplib_call.py
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class FtplibCallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B321"])
+
+ def test_call_ftplib(self):
+ fdata = textwrap.dedent(
+ """
+ from ftplib import FTP
+ FTP('ftp.debian.org')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B321", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_ftplib_import.py b/tests/unit/blacklists/test_ftplib_import.py
new file mode 100644
index 000000000..0653923ab
--- /dev/null
+++ b/tests/unit/blacklists/test_ftplib_import.py
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: Apache-2.0
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class FtplibImportTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B402"])
+
+ def test_import_ftplib(self):
+ fdata = "from ftplib import FTP"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B402", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_httpoxy_import.py b/tests/unit/blacklists/test_httpoxy_import.py
new file mode 100644
index 000000000..43ce6b4c3
--- /dev/null
+++ b/tests/unit/blacklists/test_httpoxy_import.py
@@ -0,0 +1,89 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class HttpoxyImportTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B412"])
+
+ def test_wsgiref_handlers(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ from wsgiref import handlers
+
+ def application(environ, start_response):
+ r = requests.get('https://192.168.0.42/api/foobar', timeout=30)
+ start_response('200 OK', [('Content-Type', 'text/plain')])
+ return [r.content]
+
+ if __name__ == '__main__':
+ wsgiref.handlers.CGIHandler().run(application)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B412", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_ACCESS_CONTROL, issue.cwe.id)
+ self.assertEqual(11, issue.lineno)
+ self.assertEqual([11], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_twisted_web_twcgi_cgiscript(self):
+ fdata = textwrap.dedent(
+ """
+ from twisted.internet import reactor
+ from twisted.web import static, server, twcgi
+
+ root = static.File("/root")
+ root.putChild(
+ "login.cgi",
+ twcgi.CGIScript("/var/www/cgi-bin/login.py"),
+ )
+ reactor.listenTCP(80, server.Site(root))
+ reactor.run()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B412", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_ACCESS_CONTROL, issue.cwe.id)
+ self.assertEqual(8, issue.lineno)
+ self.assertEqual([8], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_twisted_web_twcgi_cgidirectory(self):
+ fdata = textwrap.dedent(
+ """
+ from twisted.internet import reactor
+ from twisted.web import static, server, twcgi
+
+ root = static.File("/root")
+ root.putChild(
+ "cgi-bin",
+ twcgi.CGIDirectory("/var/www/cgi-bin"),
+ )
+ reactor.listenTCP(80, server.Site(root))
+ reactor.run()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B412", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_ACCESS_CONTROL, issue.cwe.id)
+ self.assertEqual(8, issue.lineno)
+ self.assertEqual([8], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
diff --git a/tests/unit/blacklists/test_mark_safe_call.py b/tests/unit/blacklists/test_mark_safe_call.py
new file mode 100644
index 000000000..dd3ad6410
--- /dev/null
+++ b/tests/unit/blacklists/test_mark_safe_call.py
@@ -0,0 +1,30 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class MarkSafeTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B308"])
+
+ def test_django_utils_safestring_mark_safe(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+
+ safestring.mark_safe('Hello World')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B308", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.XSS, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_marshal_deserialize_call.py b/tests/unit/blacklists/test_marshal_deserialize_call.py
new file mode 100644
index 000000000..d35ba0e49
--- /dev/null
+++ b/tests/unit/blacklists/test_marshal_deserialize_call.py
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class MarshalDeserializeCallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B302"])
+
+ def test_marshal_load(self):
+ fdata = textwrap.dedent(
+ """
+ import marshal
+ import tempfile
+
+ file_obj = tempfile.TemporaryFile()
+ marshal.dump(range(5), file_obj)
+ file_obj.seek(0)
+ marshal.load(file_obj)
+ file_obj.close()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B302", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA,
+ issue.cwe.id,
+ )
+ self.assertEqual(8, issue.lineno)
+ self.assertEqual([8], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_marshal_loads(self):
+ fdata = textwrap.dedent(
+ """
+ import marshal
+
+ serialized = marshal.dumps({'a': 1})
+ marshal.loads(serialized)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B302", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA,
+ issue.cwe.id,
+ )
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_md5_call.py b/tests/unit/blacklists/test_md5_call.py
new file mode 100644
index 000000000..76d3f2f6d
--- /dev/null
+++ b/tests/unit/blacklists/test_md5_call.py
@@ -0,0 +1,234 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class Md5CallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B303"])
+
+ def test_hashlib_md5(self):
+ fdata = textwrap.dedent(
+ """
+ import hashlib
+ hashlib.md5(1)
+ """
+ )
+ self.visitor.process(fdata)
+ if sys.version_info >= (3, 9):
+ self.assertEqual(0, len(self.visitor.tester.results))
+ else:
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_sha1(self):
+ fdata = textwrap.dedent(
+ """
+ import hashlib
+ hashlib.sha1(1)
+ """
+ )
+ self.visitor.process(fdata)
+ if sys.version_info >= (3, 9):
+ self.assertEqual(0, len(self.visitor.tester.results))
+ else:
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_crypto_hash_md2_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Hash import MD2 as pycrypto_md2
+ pycrypto_md2.new()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_crypto_hash_md4_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Hash import MD4 as pycrypto_md4
+ pycrypto_md4.new()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_crypto_hash_md5_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Hash import MD5 as pycrypto_md5
+ pycrypto_md5.new()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_crypto_hash_sha_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Hash import SHA as pycrypto_sha
+ pycrypto_sha.new()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_hash_md2_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Hash import MD2 as pycryptodomex_md2
+ pycryptodomex_md2.new()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_hash_md4_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Hash import MD4 as pycryptodomex_md4
+ pycryptodomex_md4.new()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_hash_md5_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Hash import MD5 as pycryptodomex_md5
+ pycryptodomex_md5.new()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptodome_hash_sha_new(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Hash import SHA as pycryptodomex_sha
+ pycryptodomex_sha.new()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptography_hazmat_primitives_hashes_md5(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat.primitives import hashes
+ hashes.MD5()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptography_hazmat_primitives_hashes_sha1(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat.primitives import hashes
+ hashes.SHA1()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B303", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_mktemp.py b/tests/unit/blacklists/test_mktemp.py
new file mode 100644
index 000000000..d9116e6e9
--- /dev/null
+++ b/tests/unit/blacklists/test_mktemp.py
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class MktempTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B306"])
+
+ def test_mktemp(self):
+ fdata = textwrap.dedent(
+ """
+ from tempfile import mktemp
+ mktemp('foo')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B306", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSECURE_TEMP_FILE, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_pickle_call.py b/tests/unit/blacklists/test_pickle_call.py
new file mode 100644
index 000000000..fd124b02b
--- /dev/null
+++ b/tests/unit/blacklists/test_pickle_call.py
@@ -0,0 +1,280 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class PickleCallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B301"])
+
+ def test_pickle_loads(self):
+ fdata = textwrap.dedent(
+ """
+ import pickle
+ pick = pickle.dumps({'a': 'b', 'c': 'd'})
+ pickle.loads(pick)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pickle_load(self):
+ fdata = textwrap.dedent(
+ """
+ import io
+ import pickle
+ file_obj = io.BytesIO()
+ pickle.dump([1, 2, '3'], file_obj)
+ file_obj.seek(0)
+ pickle.load(file_obj)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pickle_unpickler(self):
+ fdata = textwrap.dedent(
+ """
+ import io
+ import pickle
+ file_obj = io.BytesIO()
+ pickle.dump([1, 2, '3'], file_obj)
+ file_obj.seek(0)
+ pickle.Unpickler(file_obj)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_dill_loads(self):
+ fdata = textwrap.dedent(
+ """
+ import dill
+ pick = dill.dumps({'a': 'b', 'c': 'd'})
+ dill.loads(pick)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_dill_load(self):
+ fdata = textwrap.dedent(
+ """
+ import io
+ import dill
+ file_obj = io.BytesIO()
+ dill.dump([1, 2, '3'], file_obj)
+ file_obj.seek(0)
+ dill.load(file_obj)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_dill_unpickler(self):
+ fdata = textwrap.dedent(
+ """
+ import io
+ import dill
+ file_obj = io.BytesIO()
+ dill.dump([1, 2, '3'], file_obj)
+ file_obj.seek(0)
+ dill.Unpickler(file_obj)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_shelve_open(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ import shelve
+ with tempfile.TemporaryDirectory() as d:
+ filename = os.path.join(d, 'shelf')
+ shelve.open(filename)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_shelve_dbfilenameshelf(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ import shelve
+ with tempfile.TemporaryDirectory() as d:
+ filename = os.path.join(d, 'shelf')
+ shelve.DbfilenameShelf(filename)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_jsonpickle_decode(self):
+ fdata = textwrap.dedent(
+ """
+ import jsonpickle
+ pick = jsonpickle.encode({'a': 'b', 'c': 'd'})
+ jsonpickle.decode(pick)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_jsonpickle_unpickler_decode(self):
+ fdata = textwrap.dedent(
+ """
+ import jsonpickle
+ pick = jsonpickle.encode({'a': 'b', 'c': 'd'})
+ jsonpickle.unpickler.decode(pick)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_jsonpickle_unpickler_unpickler(self):
+ fdata = textwrap.dedent(
+ """
+ import jsonpickle
+ pick = jsonpickle.encode({'a': 'b', 'c': 'd'})
+ jsonpickle.unpickler.Unpickler().restore(pick)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pandas_read_pickle(self):
+ fdata = textwrap.dedent(
+ """
+ import pandas
+ df = pandas.DataFrame({"col_A": [1, 2]})
+ pick = pickle.dumps(df)
+ pandas.read_pickle(pick)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B301", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_pickle_import.py b/tests/unit/blacklists/test_pickle_import.py
new file mode 100644
index 000000000..aba2baeec
--- /dev/null
+++ b/tests/unit/blacklists/test_pickle_import.py
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: Apache-2.0
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class PicklemportTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B403"])
+
+ def test_import_pickle(self):
+ fdata = "import pickle"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B403", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_dill(self):
+ fdata = "import dill"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B403", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_shelve(self):
+ fdata = "import shelve"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B403", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.DESERIALIZATION_OF_UNTRUSTED_DATA, issue.cwe.id
+ )
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_pycrypto_import.py b/tests/unit/blacklists/test_pycrypto_import.py
new file mode 100644
index 000000000..a86f7cc27
--- /dev/null
+++ b/tests/unit/blacklists/test_pycrypto_import.py
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class PycryptoImportTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B413"])
+
+ def test_import_crypto_cipher(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.Cipher import AES
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B413", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_crypto_hash(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto import Hash
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B413", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_crypto_io(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto import IO
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B413", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_crypto_protocol(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto import Protocol
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B413", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_crypto_publickey(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto import PublicKey
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B413", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_crypto_random(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto import Random
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B413", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_crypto_signature(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto import Signature
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B413", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_import_crypto_util(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto import Util
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B413", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_pycryptodome_import.py b/tests/unit/blacklists/test_pycryptodome_import.py
new file mode 100644
index 000000000..3e97a1931
--- /dev/null
+++ b/tests/unit/blacklists/test_pycryptodome_import.py
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+from tests.unit.blacklists import base_test_case
+
+
+class PycryptodomeImportTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B414"])
+
+ def test_import_cryptodome(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.Cipher import AES
+ from Cryptodome import Random
+
+ from . import CryptoMaterialsCacheEntry
+
+ def test_pycrypto():
+ key = b'Sixteen byte key'
+ iv = Random.new().read(AES.block_size)
+ cipher = pycrypto_arc2.new(key, AES.MODE_CFB, iv)
+ factory = CryptoMaterialsCacheEntry()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/blacklists/test_pyghmi_import.py b/tests/unit/blacklists/test_pyghmi_import.py
new file mode 100644
index 000000000..9d1bcf692
--- /dev/null
+++ b/tests/unit/blacklists/test_pyghmi_import.py
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class PyghmiImportTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B415"])
+
+ def test_import_pyghmi(self):
+ fdata = textwrap.dedent(
+ """
+ from pyghmi.ipmi import command
+ cmd = command.Command(
+ bmc="bmc",
+ userid="userid",
+ password="ZjE4ZjI0NTE4YmI2NGJjZDliOGY3ZmJiY2UyN2IzODQK"
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B415", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_random_call.py b/tests/unit/blacklists/test_random_call.py
new file mode 100644
index 000000000..61b586de7
--- /dev/null
+++ b/tests/unit/blacklists/test_random_call.py
@@ -0,0 +1,177 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class RandomCallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B311"])
+
+ def test_random_random(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random.random()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B311", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSUFFICIENT_RANDOM_VALUES, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_random_randrange(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random.randrange()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B311", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSUFFICIENT_RANDOM_VALUES, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_random_randint(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random.randint()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B311", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSUFFICIENT_RANDOM_VALUES, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_random_choice(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random.choice()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B311", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSUFFICIENT_RANDOM_VALUES, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_random_choices(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random.choices()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B311", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSUFFICIENT_RANDOM_VALUES, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_random_uniform(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random.uniform()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B311", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSUFFICIENT_RANDOM_VALUES, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_random_triangular(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random.triangular()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B311", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSUFFICIENT_RANDOM_VALUES, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_random(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.urandom()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_random_systemrandom(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random.SystemRandom()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_unknown_random(self):
+ fdata = textwrap.dedent(
+ """
+ import random
+ random()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_somelib_random(self):
+ fdata = textwrap.dedent(
+ """
+ import somelib
+ somelib.a.random()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/blacklists/test_telnetlib_call.py b/tests/unit/blacklists/test_telnetlib_call.py
new file mode 100644
index 000000000..d3856978d
--- /dev/null
+++ b/tests/unit/blacklists/test_telnetlib_call.py
@@ -0,0 +1,29 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class TelnetlibCallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B312"])
+
+ def test_call_telnetlib(self):
+ fdata = textwrap.dedent(
+ """
+ import telnetlib
+ telnetlib.Telnet('localhost')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B312", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_telnetlib_import.py b/tests/unit/blacklists/test_telnetlib_import.py
new file mode 100644
index 000000000..c79f3fb7c
--- /dev/null
+++ b/tests/unit/blacklists/test_telnetlib_import.py
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: Apache-2.0
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class TelnetlibImportTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B401"])
+
+ def test_import_telnetlib(self):
+ fdata = "import telnetlib"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B401", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/blacklists/test_unverified_context_call.py b/tests/unit/blacklists/test_unverified_context_call.py
new file mode 100644
index 000000000..754862925
--- /dev/null
+++ b/tests/unit/blacklists/test_unverified_context_call.py
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.blacklists import base_test_case
+
+
+class UnverifiedContextCallTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B323"])
+
+ def test_create_unverified_context(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ ssl._create_unverified_context()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B323", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_create_default_context(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ ssl.create_default_context()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/__init__.py b/tests/unit/plugins/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/unit/plugins/base_test_case.py b/tests/unit/plugins/base_test_case.py
new file mode 100644
index 000000000..f1ce5248e
--- /dev/null
+++ b/tests/unit/plugins/base_test_case.py
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: Apache-2.0
+import testtools
+
+from bandit.core import config
+from bandit.core import manager
+from bandit.core import meta_ast
+from bandit.core import metrics
+from bandit.core import node_visitor
+from bandit.core import test_set
+
+
+class BaseTestCase(testtools.TestCase):
+ def setUp(self, test_ids):
+ super().setUp()
+ b_config = config.BanditConfig()
+ self.b_manager = manager.BanditManager(b_config, "file")
+ issue_metrics = metrics.Metrics()
+ issue_metrics.begin("test.py")
+ self.visitor = node_visitor.BanditNodeVisitor(
+ "test.py",
+ None,
+ metaast=meta_ast.BanditMetaAst(),
+ testset=test_set.BanditTestSet(
+ b_config,
+ profile={
+ "include": test_ids,
+ "exclude": [],
+ },
+ ),
+ debug=False,
+ nosec_lines={},
+ metrics=issue_metrics,
+ )
diff --git a/tests/unit/plugins/test_app_debug.py b/tests/unit/plugins/test_app_debug.py
new file mode 100644
index 000000000..5ea248ab1
--- /dev/null
+++ b/tests/unit/plugins/test_app_debug.py
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class FlaskDebugTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B201"])
+
+ def test_app_run_debug_true(self):
+ fdata = textwrap.dedent(
+ """
+ from flask import Flask
+ app = Flask(__name__)
+ app.run(debug=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CODE_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_app_run_debug_false(self):
+ fdata = textwrap.dedent(
+ """
+ from flask import Flask
+ app = Flask(__name__)
+ app.run(debug=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_app_run(self):
+ fdata = textwrap.dedent(
+ """
+ from flask import Flask
+ app = Flask(__name__)
+ app.run()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_app_run_no_import(self):
+ fdata = textwrap.dedent(
+ """
+ app = Flask(__name__)
+ app.run(debug=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_unrelated_run(self):
+ fdata = textwrap.dedent(
+ """
+ from flask import Flask
+ run(debug=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_asserts.py b/tests/unit/plugins/test_asserts.py
new file mode 100644
index 000000000..5be2f6c73
--- /dev/null
+++ b/tests/unit/plugins/test_asserts.py
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: Apache-2.0
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class AssertsTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B101"])
+
+ def test_asserts(self):
+ fdata = "assert True"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/plugins/test_crypto_request_no_cert_validation.py b/tests/unit/plugins/test_crypto_request_no_cert_validation.py
new file mode 100644
index 000000000..9b710d442
--- /dev/null
+++ b/tests/unit/plugins/test_crypto_request_no_cert_validation.py
@@ -0,0 +1,497 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class CryptoRequestNoCertValidationTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B501"])
+
+ def test_requests_get_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.get('https://example.com', timeout=30, verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_get_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.get('https://example.com', timeout=30, verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_post_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.post('https://example.com', timeout=30, verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_post_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.post('https://example.com', timeout=30, verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_put_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.put('https://example.com', timeout=30, verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_put_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.put('https://example.com', timeout=30, verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_delete_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.delete('https://example.com', timeout=30, verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_delete_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.delete('https://example.com', timeout=30, verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_patch_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.patch('https://example.com', timeout=30, verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_patch_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.patch('https://example.com', timeout=30, verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_options_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.options('https://example.com', timeout=30, verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_options_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.options('https://example.com', timeout=30, verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_head_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.head('https://example.com', timeout=30, verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_head_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.head('https://example.com', timeout=30, verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_request_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.request('GET', 'https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_request_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.request('GET', 'https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_get_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.get('https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_get_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.get('https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_options_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.options('https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_options_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.options('https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_head_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.head('https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_head_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.head('https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_post_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.post('https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_post_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.post('https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_put_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.put('https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_put_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.put('https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_patch_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.patch('https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_patch_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.patch('https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_delete_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.delete('https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_delete_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.delete('https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_stream_verify_true(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.stream('https://example.com', verify=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_stream_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.stream('https://example.com', verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_client_default(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.Client()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_client_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.Client(verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_httpx_asyncclient_default(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.AsyncClient()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_httpx_asyncclient_verify_false(self):
+ fdata = textwrap.dedent(
+ """
+ import httpx
+ httpx.AsyncClient(verify=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/plugins/test_django_sql_injection.py b/tests/unit/plugins/test_django_sql_injection.py
new file mode 100644
index 000000000..90bd89119
--- /dev/null
+++ b/tests/unit/plugins/test_django_sql_injection.py
@@ -0,0 +1,386 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class DjangoSqlInjectionTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B610", "B611"])
+
+ def test_django_user_objects_filter_extra_select_where_tables(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(
+ select={'test': 'secure'},
+ where=['secure'],
+ tables=['secure']
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_user_objects_filter_extra_dict(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra({'test': 'secure'})
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_user_objects_filter_extra_select_dict(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(
+ select={'test': 'secure'}
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_user_objects_filter_extra_where(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(where=['secure'])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_user_objects_filter_extra_dict_obj(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(
+ dict(could_be='insecure')
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4, 5], issue.linerange)
+ else:
+ self.assertEqual([3, 4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_select_dict_obj(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(
+ select=dict(could_be='insecure')
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4, 5], issue.linerange)
+ else:
+ self.assertEqual([3, 4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_select_query_var(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ query = ('"username") AS "username", * FROM "auth_user" '
+ 'WHERE 1=1 OR "username"=? --')
+ User.objects.filter(username='admin').extra(select={'test': query})
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_select_dict_str_sub(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(
+ select={'test': '%secure' % 'nos'}
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4, 5], issue.linerange)
+ else:
+ self.assertEqual([3, 4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_select_dict_str_format(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(
+ select={'test': '{}secure'.format('nos')}
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4, 5], issue.linerange)
+ else:
+ self.assertEqual([3, 4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_where_var(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ where_var = ['1=1) OR 1=1 AND (1=1']
+ User.objects.filter(username='admin').extra(where=where_var)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_where_str(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ where_str = '1=1) OR 1=1 AND (1=1'
+ User.objects.filter(username='admin').extra(where=[where_str])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_where_str_sub(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(
+ where=['%secure' % 'nos']
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4, 5], issue.linerange)
+ else:
+ self.assertEqual([3, 4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_where_str_format(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ User.objects.filter(username='admin').extra(
+ where=['{}secure'.format('no')]
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4, 5], issue.linerange)
+ else:
+ self.assertEqual([3, 4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_tables_var(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ tables_var = [
+ 'django_content_type" WHERE "auth_user"."username"="admin'
+ ]
+ User.objects.all().extra(tables=tables_var).distinct()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_filter_extra_tables_str(self):
+ fdata = textwrap.dedent(
+ """
+ from django.contrib.auth.models import User
+ tables_str = ('django_content_type" WHERE '
+ '"auth_user"."username"="admin')
+ User.objects.all().extra(tables=[tables_str]).distinct()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B610", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_user_objects_annotate_rawsql(self):
+ fdata = textwrap.dedent(
+ """
+ from django.db.models.expressions import RawSQL
+ from django.contrib.auth.models import User
+ User.objects.annotate(val=RawSQL('secure', []))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_user_objects_annotate_rawsql_str_sub(self):
+ fdata = textwrap.dedent(
+ """
+ from django.db.models.expressions import RawSQL
+ from django.contrib.auth.models import User
+ User.objects.annotate(val=RawSQL('%secure' % 'nos', []))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B611", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(26, issue.col_offset)
+
+ def test_django_user_objects_annotate_rawsql_str_format(self):
+ fdata = textwrap.dedent(
+ """
+ from django.db.models.expressions import RawSQL
+ from django.contrib.auth.models import User
+ User.objects.annotate(val=RawSQL('{}secure'.format('no'), []))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B611", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(26, issue.col_offset)
+
+ def test_django_user_objects_annotate_rawsql_raw(self):
+ fdata = textwrap.dedent(
+ """
+ from django.db.models.expressions import RawSQL
+ from django.contrib.auth.models import User
+ raw = ('"username") AS "val" FROM "auth_user" WHERE'
+ ' "username"="admin" --')
+ User.objects.annotate(val=RawSQL(raw, []))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B611", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(26, issue.col_offset)
+
+ def test_django_user_objects_annotate_rawsql_raw_sub(self):
+ fdata = textwrap.dedent(
+ """
+ from django.db.models.expressions import RawSQL
+ from django.contrib.auth.models import User
+ raw = '"username") AS "val" FROM "auth_user"' \
+ ' WHERE "username"="admin" OR 1=%s --'
+ User.objects.annotate(val=RawSQL(raw, [0]))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B611", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(26, issue.col_offset)
diff --git a/tests/unit/plugins/test_django_xss.py b/tests/unit/plugins/test_django_xss.py
new file mode 100644
index 000000000..472d31c3f
--- /dev/null
+++ b/tests/unit/plugins/test_django_xss.py
@@ -0,0 +1,853 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class DjangoXssTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B703"])
+
+ def test_django_utils_safestring_mark_safe(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ safestring.mark_safe('secure')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_safestring_safetext(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ safestring.SafeText('secure')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_safestring_safeunicode(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ safestring.SafeUnicode('secure')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_safestring_safestring(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ safestring.SafeString('secure')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_safestring_safebytes(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ safestring.SafeBytes('secure')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_var(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ my_secure_str = 'Hello World'
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_tuple_var(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ my_secure_str, _ = ('Hello World', '')
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_var_var(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ my_secure_str, _ = ('Hello World', '')
+ also_secure_str = my_secure_str
+ safestring.mark_safe(also_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_func(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def try_secure():
+ try:
+ my_secure_str = 'Secure'
+ except Exception:
+ my_secure_str = 'Secure'
+ else:
+ my_secure_str = 'Secure'
+ finally:
+ my_secure_str = 'Secure'
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_format_secure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def format_secure():
+ safestring.mark_safe('{}'.format('secure'))
+ my_secure_str = 'secure'
+ safestring.mark_safe('{}'.format(my_secure_str))
+ safestring.mark_safe('{} {}'.format(my_secure_str, 'a'))
+ safestring.mark_safe(
+ '{} {}'.format(*[my_secure_str, 'a'])
+ )
+ my_secure_str = '{}'.format(my_secure_str)
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_percent_secure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def percent_secure():
+ safestring.mark_safe('%s' % 'secure')
+ my_secure_str = 'secure'
+ safestring.mark_safe('%s' % my_secure_str)
+ safestring.mark_safe('%s %s' % (my_secure_str, 'a'))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_with_secure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def with_secure(path):
+ with open(path) as f:
+ safestring.mark_safe('Secure')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_loop_secure(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ from django.utils import safestring
+ def loop_secure():
+ my_secure_str = ''
+
+ for i in range(ord(os.urandom(1))):
+ my_secure_str += ' Secure'
+ safestring.mark_safe(my_secure_str)
+ while ord(os.urandom(1)) % 2 == 0:
+ my_secure_str += ' Secure'
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_all_secure_case(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ from django.utils import safestring
+ def all_secure_case():
+ if ord(os.urandom(1)) % 2 == 0:
+ my_secure_str = 'Secure'
+ elif ord(os.urandom(1)) % 2 == 0:
+ my_secure_str = 'Secure'
+ else:
+ my_secure_str = 'Secure'
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_django_utils_mark_safe_my_insecure_str(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def insecure_function(text, cls=''):
+ return '
{text}
'.format(
+ text=text, cls=cls
+ )
+ my_insecure_str = insecure_function(
+ 'insecure', cls='" onload="alert("xss")'
+ )
+ safestring.mark_safe(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(10, issue.lineno)
+ self.assertEqual([10], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_utils_safetext_my_insecure_str(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def insecure_function(text, cls=''):
+ return '{text}
'.format(
+ text=text, cls=cls
+ )
+ my_insecure_str = insecure_function(
+ 'insecure', cls='" onload="alert("xss")'
+ )
+ safestring.SafeText(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(10, issue.lineno)
+ self.assertEqual([10], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_utils_safeunicode_my_insecure_str(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def insecure_function(text, cls=''):
+ return '{text}
'.format(
+ text=text, cls=cls
+ )
+ my_insecure_str = insecure_function(
+ 'insecure', cls='" onload="alert("xss")'
+ )
+ safestring.SafeUnicode(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(10, issue.lineno)
+ self.assertEqual([10], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_utils_safestring_my_insecure_str(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def insecure_function(text, cls=''):
+ return '{text}
'.format(
+ text=text, cls=cls
+ )
+ my_insecure_str = insecure_function(
+ 'insecure', cls='" onload="alert("xss")'
+ )
+ safestring.SafeString(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(10, issue.lineno)
+ self.assertEqual([10], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_utils_safebytes_my_insecure_str(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def insecure_function(text, cls=''):
+ return '{text}
'.format(
+ text=text, cls=cls
+ )
+ my_insecure_str = insecure_function(
+ 'insecure', cls='" onload="alert("xss")'
+ )
+ safestring.SafeBytes(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(10, issue.lineno)
+ self.assertEqual([10], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_django_utils_mark_safe_try_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def try_insecure(cls='" onload="alert("xss")'):
+ try:
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ except Exception:
+ my_insecure_str = 'Secure'
+ safestring.mark_safe(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(8, issue.lineno)
+ self.assertEqual([8], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_except_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def except_insecure(cls='" onload="alert("xss")'):
+ try:
+ my_insecure_str = 'Secure'
+ except Exception:
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(8, issue.lineno)
+ self.assertEqual([8], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_try_else_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def try_else_insecure(cls='" onload="alert("xss")'):
+ try:
+ if 1 == random.randint(0, 1): # nosec
+ raise Exception
+ except Exception:
+ my_insecure_str = 'Secure'
+ else:
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(11, issue.lineno)
+ self.assertEqual([11], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_finally_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def finally_insecure(cls='" onload="alert("xss")'):
+ try:
+ if 1 == random.randint(0, 1): # nosec
+ raise Exception
+ except Exception:
+ print("Exception")
+ else:
+ print("No Exception")
+ finally:
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe(my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(13, issue.lineno)
+ self.assertEqual([13], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_format_arg_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def format_arg_insecure(cls='" onload="alert("xss")'):
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe('{} {}'.format(
+ my_insecure_str, 'STR')
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([5, 6, 7], issue.linerange)
+ else:
+ self.assertEqual([5, 6], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_format_startarg_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def format_startarg_insecure(cls='" onload="alert("xss")'):
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe('{}'.format(*[my_insecure_str]))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_format_keywords_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def format_keywords_insecure(cls='" onload="alert("xss")'):
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe('{b}'.format(b=my_insecure_str))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_format_kwargs_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def format_kwargs_insecure(cls='" onload="alert("xss")'):
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe('{b}'.format(
+ **{'b': my_insecure_str})
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([5, 6, 7], issue.linerange)
+ else:
+ self.assertEqual([5, 6], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_percent_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def percent_insecure(cls='" onload="alert("xss")'):
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe('%s' % my_insecure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_percent_list_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def percent_list_insecure(cls='" onload="alert("xss")'):
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe('%s %s' % (my_insecure_str, 'b'))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_percent_dict_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def percent_dict_insecure(cls='" onload="alert("xss")'):
+ my_insecure_str = insecure_function('insecure', cls=cls)
+ safestring.mark_safe('%(b)s' % {'b': my_insecure_str})
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_import_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def import_insecure():
+ import sre_constants
+ safestring.mark_safe(sre_constants.ANY)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_import_as_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def import_as_insecure():
+ import sre_constants.ANY as any_str
+ safestring.mark_safe(any_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_from_import_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def from_import_insecure():
+ from sre_constants import ANY
+ safestring.mark_safe(ANY)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_from_import_as_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def from_import_as_insecure():
+ from sre_constants import ANY as any_str
+ safestring.mark_safe(any_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_with_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def with_insecure(path):
+ with open(path) as f:
+ safestring.mark_safe(f.read())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_django_utils_mark_safe_also_with_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def also_with_insecure(path):
+ with open(path) as f:
+ safestring.mark_safe(f)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_django_utils_mark_safe_for_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def for_insecure():
+ my_secure_str = ''
+ for i in range(random.randint(0, 1)): # nosec
+ my_secure_str += insecure_function(
+ 'insecure', cls='" onload="alert("xss")'
+ )
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(9, issue.lineno)
+ self.assertEqual([9], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_while_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ from django.utils import safestring
+ def while_insecure():
+ my_secure_str = ''
+ while ord(os.urandom(1)) % 2 == 0:
+ my_secure_str += insecure_function(
+ 'insecure', cls='" onload="alert("xss")'
+ )
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(10, issue.lineno)
+ self.assertEqual([10], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_some_insecure_case(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ from django.utils import safestring
+ def some_insecure_case():
+ if ord(os.urandom(1)) % 2 == 0:
+ my_secure_str = insecure_function(
+ 'insecure', cls='" onload="alert("xss")'
+ )
+ elif ord(os.urandom(1)) % 2 == 0:
+ my_secure_str = 'Secure'
+ else:
+ my_secure_str = 'Secure'
+ safestring.mark_safe(my_secure_str)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(13, issue.lineno)
+ self.assertEqual([13], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_test_insecure_shadow(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ mystr = 'insecure'
+ def test_insecure_shadow(): # var assigned out of scope
+ safestring.mark_safe(mystr)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(5, issue.lineno)
+ self.assertEqual([5], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_test_insecure(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def test_insecure(str_arg):
+ safestring.mark_safe(str_arg)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_test_insecure_with_assign(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def test_insecure_with_assign(str_arg=None):
+ if not str_arg:
+ str_arg = 'could be insecure'
+ safestring.mark_safe(str_arg)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(6, issue.lineno)
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
+
+ def test_django_utils_mark_safe_test_insecure_tuple_assign(self):
+ fdata = textwrap.dedent(
+ """
+ from django.utils import safestring
+ def test_insecure_tuple_assign():
+ HTML_CHOICES = (
+ (_('Donate'), 'https://example.org/donate/'),
+ (_('More info'), 'https://example.org/'),
+ )
+ text, url = choice(HTML_CHOICES)
+ safestring.mark_safe('{1}'.format(url, text))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B703", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(9, issue.lineno)
+ self.assertEqual([9], issue.linerange)
+ self.assertEqual(4, issue.col_offset)
diff --git a/tests/unit/plugins/test_exec.py b/tests/unit/plugins/test_exec.py
new file mode 100644
index 000000000..db71bbe3c
--- /dev/null
+++ b/tests/unit/plugins/test_exec.py
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier: Apache-2.0
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class ExecTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B102"])
+
+ def test_exec_used(self):
+ fdata = "exec('do evil')"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/plugins/test_general_bad_file_permissions.py b/tests/unit/plugins/test_general_bad_file_permissions.py
new file mode 100644
index 000000000..0bd2b4dd0
--- /dev/null
+++ b/tests/unit/plugins/test_general_bad_file_permissions.py
@@ -0,0 +1,212 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class GeneralBadFilePermissionsTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B103"])
+
+ def test_chmod_octal_227(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/etc/passwd', 0o227)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_octal_7(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/etc/passwd', 0o7)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_octal_664(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/etc/passwd', 0o664)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_octal_777(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/etc/passwd', 0o777)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_octal_770(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/etc/passwd', 0o770)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_octal_776(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/etc/passwd', 0o776)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_octal_760(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/etc/passwd', 0o760)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_decimal_511(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('~/.bashrc', 511)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_hex_1ff(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/tmp/oh_hai', 0x1ff)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_chmod_stat_s_irwxu(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.chmod('/etc/passwd', stat.S_IRWXU)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_chmod_file_as_arg(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ key_file = 'foo'
+ os.chmod(key_file, 0o777)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INCORRECT_PERMISSION_ASSIGNMENT, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/plugins/test_general_bind_all_interfaces.py b/tests/unit/plugins/test_general_bind_all_interfaces.py
new file mode 100644
index 000000000..91412b16e
--- /dev/null
+++ b/tests/unit/plugins/test_general_bind_all_interfaces.py
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class GeneralBindAllInterfacesTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B104"])
+
+ def test_bind_all_interfaces(self):
+ fdata = textwrap.dedent(
+ """
+ import socket
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.bind(('0.0.0.0', 31137))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.MULTIPLE_BINDS, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_bind_address(self):
+ fdata = textwrap.dedent(
+ """
+ import socket
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.bind(('192.168.0.1', 8080))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_general_hardcoded_password.py b/tests/unit/plugins/test_general_hardcoded_password.py
new file mode 100644
index 000000000..1acf1ca2f
--- /dev/null
+++ b/tests/unit/plugins/test_general_hardcoded_password.py
@@ -0,0 +1,250 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class GeneralHardcodedPasswordTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B105", "B106", "B107"])
+
+ def test_class_attribute(self):
+ fdata = textwrap.dedent(
+ """
+ class SomeClass:
+ password = "class_password"
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(15, issue.col_offset)
+
+ def test_function_kwarg(self):
+ fdata = textwrap.dedent(
+ """
+ def someFunction(user, password="Admin"):
+ print("Hi " + user)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B107", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([2, 3], issue.linerange)
+ else:
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_function_password_eq_root(self):
+ fdata = textwrap.dedent(
+ """
+ def someFunction2(password):
+ if password == "root":
+ print("OK, logged in")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(19, issue.col_offset)
+
+ def test_function_password_eq_empty(self):
+ fdata = textwrap.dedent(
+ """
+ def noMatch(password):
+ if password == '':
+ print("No password!")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(19, issue.col_offset)
+
+ def test_function_password_eq_ajklawejrkl42348swfgkg(self):
+ fdata = textwrap.dedent(
+ """
+ def NoMatch2(password):
+ if password == "ajklawejrkl42348swfgkg":
+ print("Nice password!")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(19, issue.col_offset)
+
+ def test_function_obj_password_eq(self):
+ fdata = textwrap.dedent(
+ """
+ def noMatchObject():
+ obj = SomeClass()
+ if obj.password == "this cool password":
+ print(obj.password)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(23, issue.col_offset)
+
+ def test_function_kwarg2(self):
+ fdata = textwrap.dedent(
+ """
+ def doLogin(password="blerg"):
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B107", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([2, 3], issue.linerange)
+ else:
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_function_no_password(self):
+ fdata = textwrap.dedent(
+ """
+ def NoMatch3(a, b):
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_call_kwarg(self):
+ fdata = 'doLogin(password="blerg")'
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B106", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_password_blerg(self):
+ fdata = 'password = "blerg"'
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(11, issue.col_offset)
+
+ def test_dict_password_blerg(self):
+ fdata = 'd["password"] = "blerg"'
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(2, issue.col_offset)
+
+ def test_email_password_secret(self):
+ fdata = 'EMAIL_PASSWORD = "secret"'
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(17, issue.col_offset)
+
+ def test_email_pwd_emails_secret(self):
+ fdata = "email_pwd = 'emails_secret'"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(12, issue.col_offset)
+
+ def test_my_secret_password_for_email(self):
+ fdata = "my_secret_password_for_email = 'd6s$f9g!j8mg7hw?n&2'"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(31, issue.col_offset)
+
+ def test_passphrase_1234(self):
+ fdata = "passphrase='1234'"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B105", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.HARD_CODED_PASSWORD, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(11, issue.col_offset)
diff --git a/tests/unit/plugins/test_general_hardcoded_tmp.py b/tests/unit/plugins/test_general_hardcoded_tmp.py
new file mode 100644
index 000000000..439ae506f
--- /dev/null
+++ b/tests/unit/plugins/test_general_hardcoded_tmp.py
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class GeneralHardcodedTmpTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B108"])
+
+ def test_tmp(self):
+ fdata = textwrap.dedent(
+ """
+ with open('/tmp/abc', 'w') as f:
+ f.write('def')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSECURE_TEMP_FILE, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(10, issue.col_offset)
+
+ def test_var_tmp(self):
+ fdata = textwrap.dedent(
+ """
+ with open('/var/tmp/123', 'w') as f:
+ f.write('def')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSECURE_TEMP_FILE, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(10, issue.col_offset)
+
+ def test_dev_shm(self):
+ fdata = textwrap.dedent(
+ """
+ with open('/dev/shm/unit/test', 'w') as f:
+ f.write('def')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.INSECURE_TEMP_FILE, issue.cwe.id)
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ self.assertEqual(10, issue.col_offset)
+
+ def test_abc_tmp(self):
+ fdata = textwrap.dedent(
+ """
+ with open('/abc/tmp', 'w') as f:
+ f.write('def')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_foo_bar(self):
+ fdata = textwrap.dedent(
+ """
+ with open('/foo/bar', 'w') as f:
+ f.write('def')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_hashlib_insecure_functions.py b/tests/unit/plugins/test_hashlib_insecure_functions.py
new file mode 100644
index 000000000..7803437c2
--- /dev/null
+++ b/tests/unit/plugins/test_hashlib_insecure_functions.py
@@ -0,0 +1,202 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class HashlibInsecureFunctionsTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B324"])
+
+ def test_hashlib_new_md4(self):
+ fdata = "hashlib.new('md4')"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ if sys.version_info >= (3, 9):
+ self.assertEqual(bandit.HIGH, issue.severity)
+ else:
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_new_md5(self):
+ fdata = "hashlib.new('md5')"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ if sys.version_info >= (3, 9):
+ self.assertEqual(bandit.HIGH, issue.severity)
+ else:
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_new_sha(self):
+ fdata = "hashlib.new('sha')"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ if sys.version_info >= (3, 9):
+ self.assertEqual(bandit.HIGH, issue.severity)
+ else:
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_new_sha1(self):
+ fdata = "hashlib.new('sha1')"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ if sys.version_info >= (3, 9):
+ self.assertEqual(bandit.HIGH, issue.severity)
+ else:
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_new_name_md5(self):
+ fdata = "hashlib.new(name='md5', data=b'test')"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ if sys.version_info >= (3, 9):
+ self.assertEqual(bandit.HIGH, issue.severity)
+ else:
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_new_sha256(self):
+ fdata = "hashlib.new(name='sha256')"
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_hashlib_new_sha512(self):
+ fdata = "hashlib.new('SHA512')"
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_hashlib_new_usedforsecurity_true(self):
+ fdata = "hashlib.new('sha1', usedforsecurity=True)"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ if sys.version_info >= (3, 9):
+ self.assertEqual(bandit.HIGH, issue.severity)
+ else:
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_new_usedforsecurity_false(self):
+ fdata = "hashlib.new(name='sha1', usedforsecurity=False)"
+ self.visitor.process(fdata)
+ if sys.version_info >= (3, 9):
+ self.assertEqual(0, len(self.visitor.tester.results))
+ else:
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_md4(self):
+ if sys.version_info >= (3, 9):
+ fdata = "hashlib.md4()"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_md5(self):
+ if sys.version_info >= (3, 9):
+ fdata = "hashlib.md5()"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_sha(self):
+ if sys.version_info >= (3, 9):
+ fdata = "hashlib.sha()"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_sha1(self):
+ if sys.version_info >= (3, 9):
+ fdata = "hashlib.sha1()"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_hashlib_sha256(self):
+ fdata = "hashlib.sha256()"
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_hashlib_usedforsecurity_false(self):
+ if sys.version_info >= (3, 9):
+ fdata = "hashlib.md5(usedforsecurity=False)"
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_hashlib_usedforsecurity_true(self):
+ if sys.version_info >= (3, 9):
+ fdata = "hashlib.sha1(usedforsecurity=True)"
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/plugins/test_injection_paramiko.py b/tests/unit/plugins/test_injection_paramiko.py
new file mode 100644
index 000000000..6e0cb1e7e
--- /dev/null
+++ b/tests/unit/plugins/test_injection_paramiko.py
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class InjectionParamikoTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B601"])
+
+ def test_exec_command(self):
+ fdata = textwrap.dedent(
+ """
+ import paramiko
+ client = paramiko.client.SSHClient()
+ client.exec_command('something; really; unsafe')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_exec_command_no_import(self):
+ fdata = textwrap.dedent(
+ """
+ client = Client()
+ client.exec_command('test')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_injection_shell.py b/tests/unit/plugins/test_injection_shell.py
new file mode 100644
index 000000000..108a19ea3
--- /dev/null
+++ b/tests/unit/plugins/test_injection_shell.py
@@ -0,0 +1,1393 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class InjectionShellTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B602", "B603", "B604", "B605", "B606", "B607"])
+
+ def test_popen_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen
+ Popen('/bin/gcc --version', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ def Popen(*args, **kwargs):
+ print('hi')
+
+ def __len__(self):
+ return 0
+ Popen('/bin/gcc --version', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B604", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_arg_list_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen(['/bin/gcc', '--version'], shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_arg_list(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen(['/bin/gcc', '--version'])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_arg_list_multiline(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.call(["/bin/ls",
+ "-l"
+ ])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4, 5], issue.linerange)
+ else:
+ self.assertEqual([3, 4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.call('/bin/ls -l', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_check_call_arg_list_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.check_call(['/bin/ls', '-l'], shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_check_call_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.check_call('/bin/ls -l', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_check_output_arg_list(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.check_output(['/bin/ls', '-l'])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_check_output_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.check_output('/bin/ls -l', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_run_shell_arg_list(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.run(['/bin/ls', '-l'])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_run_shell_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.run('/bin/ls -l', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_wildcard_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen('/bin/ls *', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_string_sub_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen('/bin/ls %s' % ('something',), shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_string_format_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen('/bin/ls {}'.format('something'), shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_command_as_var_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = "/bin/ls" + unknown_function()
+ subprocess.Popen(command, shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_and_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen('/bin/ls && cat /etc/passwd', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell='True')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_false_str(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell='False')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_none_str(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell='None')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_1(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell=1)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_popen(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell=Popen())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_true_list(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell=[True])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_dict(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell={'IS': 'True'})
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_var(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell=command)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B602", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_0(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell=0)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_empty_list(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell=[])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_empty_dict(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell={})
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_call_command_as_var_shell_none(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ command = 'pwd'
+ subprocess.call(command, shell=None)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_system(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.system('/bin/echo hi')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_execl(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.execl(path, arg0, arg1)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_execle(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.execle(path, arg0, arg1, env)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_execlp(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.execlp(file, arg0, arg1)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_execlpe(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.execlpe(file, arg0, arg1, env)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_execv(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.execv(path, args)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_execve(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.execve(path, args, env)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_execvp(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.execvp(file, args)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_execvpe(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.execvpe(file, args, env)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_spawnl(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnl(mode, path)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_spawnle(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnle(mode, path, env)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_spawnlp(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnlp(mode, file)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_spawnlpe(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnlpe(mode, file, env)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_spawnv(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnv(mode, path, args)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_spawnve(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnve(mode, path, args, env)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_spawnvp(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnvp(mode, file, args)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_spawnvpe(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnvpe(mode, file, args, env)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_startfile_foo(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.startfile('/bin/foo.docx')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_startfile_bad(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.startfile('/bin/bad.exe')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_startfile_text(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.startfile('/bin/text.txt')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B606", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_popen_uname(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.popen('/bin/uname -av')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_popen_uname(self):
+ fdata = textwrap.dedent(
+ """
+ from os import popen
+ popen('/bin/uname -av')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_o_popen_uname(self):
+ fdata = textwrap.dedent(
+ """
+ import os as o
+ o.popen('/bin/uname -av')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pos_uname(self):
+ fdata = textwrap.dedent(
+ """
+ from os import popen as pos
+ pos('/bin/uname -av')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_popen2_uname(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.popen2('/bin/uname -av')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_popen3_uname(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.popen3('/bin/uname -av')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_popen4_uname(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.popen4('/bin/uname -av')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_popen4_uname_rm(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.popen4('/bin/uname -av; rm -rf /')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_popen4_some_var(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.popen4(some_var)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pop_gcc_partial_path(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen as pop
+ pop('gcc --version', shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(2, len(self.visitor.tester.results))
+ issue1 = self.visitor.tester.results[0]
+ self.assertEqual("B607", issue1.test_id)
+ self.assertEqual(bandit.LOW, issue1.severity)
+ self.assertEqual(bandit.HIGH, issue1.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue1.cwe.id)
+ self.assertEqual(3, issue1.lineno)
+ self.assertEqual([3], issue1.linerange)
+ self.assertEqual(0, issue1.col_offset)
+ issue2 = self.visitor.tester.results[1]
+ self.assertEqual("B603", issue2.test_id)
+ self.assertEqual(bandit.LOW, issue2.severity)
+ self.assertEqual(bandit.HIGH, issue2.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue2.cwe.id)
+ self.assertEqual(3, issue2.lineno)
+ self.assertEqual([3], issue2.linerange)
+ self.assertEqual(0, issue2.col_offset)
+
+ def test_pop_gcc_absolute_path(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen as pop
+ pop('/bin/gcc --version', shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pop_var_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen as pop
+ pop(var, shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pop_partial_path_arg_list_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen as pop
+ pop(['ls', '-l'], shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(2, len(self.visitor.tester.results))
+ issue1 = self.visitor.tester.results[0]
+ self.assertEqual("B607", issue1.test_id)
+ self.assertEqual(bandit.LOW, issue1.severity)
+ self.assertEqual(bandit.HIGH, issue1.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue1.cwe.id)
+ self.assertEqual(3, issue1.lineno)
+ self.assertEqual([3], issue1.linerange)
+ self.assertEqual(0, issue1.col_offset)
+ issue2 = self.visitor.tester.results[1]
+ self.assertEqual("B603", issue2.test_id)
+ self.assertEqual(bandit.LOW, issue2.severity)
+ self.assertEqual(bandit.HIGH, issue2.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue2.cwe.id)
+ self.assertEqual(3, issue2.lineno)
+ self.assertEqual([3], issue2.linerange)
+ self.assertEqual(0, issue2.col_offset)
+
+ def test_pop_absolute_path_arg_list_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen as pop
+ pop(['/bin/ls', '-l'], shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pop_ls_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen as pop
+ pop('../ls -l', shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pop_windows_path_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen as pop
+ pop('c:\\hello\\something', shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pop_linux_path_shell_false(self):
+ fdata = textwrap.dedent(
+ """
+ from subprocess import Popen as pop
+ pop('c:/hello/something_else', shell=False)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B603", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_commands_getstatusoutput(self):
+ fdata = textwrap.dedent(
+ """
+ import commands
+ print(commands.getstatusoutput('/bin/echo / | xargs ls'))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(6, issue.col_offset)
+
+ def test_commands_getoutput(self):
+ fdata = textwrap.dedent(
+ """
+ import commands
+ print(commands.getoutput('/bin/echo / | xargs ls'))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(6, issue.col_offset)
+
+ def test_commands_getstatus(self):
+ fdata = textwrap.dedent(
+ """
+ import commands
+ print(commands.getstatus('/bin/echo / | xargs ls'))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_popen2_popen2(self):
+ fdata = textwrap.dedent(
+ """
+ import popen2
+ print(popen2.popen2('/bin/echo / | xargs ls')[0].read())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(6, issue.col_offset)
+
+ def test_popen2_popen3(self):
+ fdata = textwrap.dedent(
+ """
+ import popen2
+ print(popen2.popen3('/bin/echo / | xargs ls')[0].read())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(6, issue.col_offset)
+
+ def test_popen2_popen4(self):
+ fdata = textwrap.dedent(
+ """
+ import popen2
+ print(popen2.popen4('/bin/echo / | xargs ls')[0].read())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(6, issue.col_offset)
+
+ def test_popen2_popen3_fromchild_read(self):
+ fdata = textwrap.dedent(
+ """
+ import popen2
+ print(popen2.Popen3('/bin/echo / | xargs ls').fromchild.read())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(6, issue.col_offset)
+
+ def test_popen2_popen4_fromchild_read(self):
+ fdata = textwrap.dedent(
+ """
+ import popen2
+ print(popen2.Popen3('/bin/echo / | xargs ls').fromchild.read())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B605", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.OS_COMMAND_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(6, issue.col_offset)
diff --git a/tests/unit/plugins/test_injection_sql.py b/tests/unit/plugins/test_injection_sql.py
new file mode 100644
index 000000000..30f8f0e6c
--- /dev/null
+++ b/tests/unit/plugins/test_injection_sql.py
@@ -0,0 +1,238 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class InsecureSqlTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B608"])
+
+ def test_query_select_from_where(self):
+ fdata = """query = "SELECT * FROM foo WHERE id = '%s'" % identifier"""
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_query_insert_into_values(self):
+ fdata = """query = "INSERT INTO foo VALUES ('a', 'b', '%s')" % value"""
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_query_delete_from_where(self):
+ fdata = """query = "DELETE FROM foo WHERE id = '%s'" % identifier"""
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_query_update_set_where(self):
+ fdata = (
+ """query = "UPDATE foo SET value = 'b' WHERE id = """
+ """'%s'" % identifier"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_query_with_as_select_from_select_from_where(self):
+ fdata = '''query = """WITH cte AS (SELECT x FROM foo)
+ SELECT x FROM cte WHERE x = '%s'""" % identifier
+ '''
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ if sys.version_info >= (3, 8):
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1, 2], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+ else:
+ self.assertEqual(2, issue.lineno)
+ self.assertEqual([2], issue.linerange)
+ # FIXME: col_offset should never be negative
+ self.assertEqual(-1, issue.col_offset)
+
+ def test_query_select_from_where_identifier(self):
+ fdata = """query = "SELECT * FROM foo WHERE id = '" + identifier + "'"
+ """
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_query_select_from_where_format_identifier(self):
+ fdata = (
+ """query = "SELECT * FROM foo WHERE id = """
+ """'{}'".format(identifier)"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(8, issue.col_offset)
+
+ def test_execute_select_from_where_identifier(self):
+ fdata = (
+ """cur.execute("SELECT * FROM foo WHERE id = '%s'" """
+ """% identifier)"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(12, issue.col_offset)
+
+ def test_execute_insert_values(self):
+ fdata = (
+ """cur.execute("INSERT INTO foo VALUES ('a', 'b', '%s')" """
+ """% value)"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(12, issue.col_offset)
+
+ def test_execute_delete_from_where_identifier(self):
+ fdata = """cur.execute("DELETE FROM foo WHERE id = '%s'" % identifier)
+ """
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(12, issue.col_offset)
+
+ def test_execute_update_set_where_identifier(self):
+ fdata = (
+ """cur.execute("UPDATE foo SET value = 'b' WHERE id = """
+ """'%s'" % identifier)"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(12, issue.col_offset)
+
+ def test_execute_select_from_where_identifier_2(self):
+ fdata = (
+ """cur.execute("SELECT * FROM foo WHERE id = """
+ """'" + identifier + "'")"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(12, issue.col_offset)
+
+ def test_execute_select_from_where_identifier_format(self):
+ fdata = (
+ """cur.execute("SELECT * FROM foo WHERE id = """
+ """'{}'".format(identifier))"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.SQL_INJECTION, issue.cwe.id)
+ self.assertEqual(1, issue.lineno)
+ self.assertEqual([1], issue.linerange)
+ self.assertEqual(12, issue.col_offset)
+
+ def test_execute_select_from_where_identifier_good(self):
+ fdata = """cur.execute("SELECT * FROM foo WHERE id = '%s'", identifier)
+ """
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_execute_insert_into_values_good(self):
+ fdata = (
+ """cur.execute("INSERT INTO foo VALUES ('a', 'b', '%s')", """
+ """value)"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_execute_delete_from_where_good(self):
+ fdata = """cur.execute("DELETE FROM foo WHERE id = '%s'", identifier)
+ """
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_execute_update_set_where_good(self):
+ fdata = (
+ """cur.execute("UPDATE foo SET value = 'b' WHERE id = """
+ """'%s'", identifier)"""
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_non_sql_select_statement(self):
+ fdata = """choices=[('server_list', _("Select from active instances"))]
+ """
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_non_sql_delete_statement(self):
+ fdata = """print("delete from the cache as the first argument")
+ """
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_injection_wildcard.py b/tests/unit/plugins/test_injection_wildcard.py
new file mode 100644
index 000000000..c62b16c10
--- /dev/null
+++ b/tests/unit/plugins/test_injection_wildcard.py
@@ -0,0 +1,138 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class InjectionWildcardTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B609"])
+
+ def test_os_system_tar(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.system("/bin/tar xvzf *")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_WILDCARD_NEUTRALIZATION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_system_chown(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.system('/bin/chown *')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_WILDCARD_NEUTRALIZATION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_os_system_chmod(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.popen2('/bin/chmod *')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_WILDCARD_NEUTRALIZATION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_chown_shell_true(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen('/bin/chown *', shell=True)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_WILDCARD_NEUTRALIZATION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_subprocess_popen_rsync(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen('/bin/rsync *')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_subprocess_popen_chmod(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen("/bin/chmod *")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_subprocess_popen_chown(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen(['/bin/chown', '*'])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_subprocess_popen_chmod_argv(self):
+ fdata = textwrap.dedent(
+ """
+ import subprocess
+ subprocess.Popen(["/bin/chmod", sys.argv[1], "*"],
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_os_spawnvp(self):
+ fdata = textwrap.dedent(
+ """
+ import os
+ os.spawnvp(os.P_WAIT, 'tar', ['tar', 'xvzf', '*'])
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_insecure_ssl_tls.py b/tests/unit/plugins/test_insecure_ssl_tls.py
new file mode 100644
index 000000000..8d1313f8f
--- /dev/null
+++ b/tests/unit/plugins/test_insecure_ssl_tls.py
@@ -0,0 +1,453 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class InsecureSslTlsTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B502", "B503", "B504"])
+
+ def test_ssl_wrap_socket_ssl_v2(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv2)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_ssl_wrap_socket_ssl_v3(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv3)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_ssl_wrap_socket_tls_v1(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_ssl_wrap_socket_tls_v11(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1_1)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_ssl_wrap_socket(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ ssl.wrap_socket()
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B504", issue.test_id)
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_protocol_ssl_v2(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ herp_derp(ssl_version=ssl.PROTOCOL_SSLv2)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_protocol_ssl_v3(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ herp_derp(ssl_version=ssl.PROTOCOL_SSLv3)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_protocol_tls_v1(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ herp_derp(ssl_version=ssl.PROTOCOL_TLSv1)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_protocol_tls_v11(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ herp_derp(ssl_version=ssl.PROTOCOL_TLSv1_1)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_func_protocol_ssl_v2(self):
+ fdata = textwrap.dedent(
+ """
+ import ssl
+ def open_ssl_socket(version=ssl.PROTOCOL_SSLv2):
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B503", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4], issue.linerange)
+ else:
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pyopenssl_ssl_v2(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ SSL.Context(method=SSL.SSLv2_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pyopenssl_ssl_v23(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ SSL.Context(method=SSL.SSLv23_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pyopenssl_ssl_v3(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ SSL.Context(method=SSL.SSLv3_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pyopenssl_tls_v1(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ SSL.Context(method=SSL.TLSv1_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pyopenssl_tls_v11(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ SSL.Context(method=SSL.TLSv1_1_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_pyopenssl_ssl_v2(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ herp_derp(method=SSL.SSLv2_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_pyopenssl_ssl_v23(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ herp_derp(method=SSL.SSLv23_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_pyopenssl_ssl_v3(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ herp_derp(method=SSL.SSLv3_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_pyopenssl_tls_v1(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ herp_derp(method=SSL.TLSv1_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_call_pyopenssl_tls_v11(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ herp_derp(method=SSL.TLSv1_1_METHOD)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B502", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_func_pyopenssl_ssl_v2(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ def open_ssl_socket(version=SSL.SSLv2_METHOD):
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B503", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4], issue.linerange)
+ else:
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_func_pyopenssl_ssl_v23(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ def open_ssl_socket(version=SSL.SSLv23_METHOD):
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B503", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4], issue.linerange)
+ else:
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_func_pyopenssl_tls_v11(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ def open_ssl_socket(version=SSL.TLSv1_1_METHOD):
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B503", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BROKEN_CRYPTO, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([3, 4], issue.linerange)
+ else:
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_func_pyopenssl_tls_v12(self):
+ fdata = textwrap.dedent(
+ """
+ from pyOpenSSL import SSL
+ def open_ssl_socket(version=SSL.TLSv1_2_METHOD):
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_jinja2_templates.py b/tests/unit/plugins/test_jinja2_templates.py
new file mode 100644
index 000000000..b748937ea
--- /dev/null
+++ b/tests/unit/plugins/test_jinja2_templates.py
@@ -0,0 +1,87 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class Jinja2TemplatesTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B701"])
+
+ def test_environment_autoescape_false(self):
+ fdata = textwrap.dedent(
+ """
+ import jinja2
+ templateLoader = jinja2.FileSystemLoader(searchpath="/")
+ jinja2.Environment(autoescape=False, loader=templateLoader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CODE_INJECTION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_environment_autoescape_true(self):
+ fdata = textwrap.dedent(
+ """
+ import jinja2
+ templateLoader = jinja2.FileSystemLoader(searchpath="/")
+ jinja2.Environment(autoescape=True, loader=templateLoader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_environment_autoescape_select(self):
+ fdata = textwrap.dedent(
+ """
+ import jinja2
+ from jinja2 import Environment
+ from jinja2 import select_autoescape
+ templateLoader = jinja2.FileSystemLoader(searchpath="/")
+ Environment(loader=templateLoader, autoescape=select_autoescape())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_environment_autoescape_jinja2_select(self):
+ fdata = textwrap.dedent(
+ """
+ import jinja2
+ from jinja2 import Environment
+ templateLoader = jinja2.FileSystemLoader(searchpath="/")
+ Environment(loader=templateLoader,
+ autoescape=jinja2.select_autoescape(['html', 'htm', 'xml']))
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_environment_autoescape_func(self):
+ fdata = textwrap.dedent(
+ """
+ import jinja2
+ from jinja2 import Environment
+ templateLoader = jinja2.FileSystemLoader(searchpath="/")
+ def fake_func():
+ return 'foobar'
+ Environment(loader=templateLoader, autoescape=fake_func())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CODE_INJECTION, issue.cwe.id)
+ self.assertEqual(7, issue.lineno)
+ self.assertEqual([7], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/plugins/test_logging_config_insecure_listen.py b/tests/unit/plugins/test_logging_config_insecure_listen.py
new file mode 100644
index 000000000..8fc8d347b
--- /dev/null
+++ b/tests/unit/plugins/test_logging_config_insecure_listen.py
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class LoggingConfigListenTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B612"])
+
+ def test_logging_config_listen(self):
+ fdata = textwrap.dedent(
+ """
+ from logging import config
+ server = config.listen(9999)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CODE_INJECTION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(9, issue.col_offset)
+
+ def test_logging_config_listen_verify(self):
+ fdata = textwrap.dedent(
+ """
+ from logging import config
+ server = config.listen(9999, verify=lambda x: x)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_mako_templates.py b/tests/unit/plugins/test_mako_templates.py
new file mode 100644
index 000000000..46316a22b
--- /dev/null
+++ b/tests/unit/plugins/test_mako_templates.py
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class MakoTemplatesTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B702"])
+
+ def test_template_template(self):
+ fdata = textwrap.dedent(
+ """
+ from mako import template
+ template.Template("hello")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_mako_template_template(self):
+ fdata = textwrap.dedent(
+ """
+ import mako
+ mako.template.Template("hello")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_template(self):
+ fdata = textwrap.dedent(
+ """
+ from mako.template import Template
+ Template("hello")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.BASIC_XSS, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/plugins/test_request_without_timeout.py b/tests/unit/plugins/test_request_without_timeout.py
new file mode 100644
index 000000000..acbaf7f50
--- /dev/null
+++ b/tests/unit/plugins/test_request_without_timeout.py
@@ -0,0 +1,347 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class RequestWithoutTimeoutTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B113"])
+
+ def test_requests_get_default(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.get('https://example.com')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_get_with_timeout_none(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.get('https://example.com', timeout=None)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_get_with_timeout(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.get('https://example.com', timeout=5)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_post_default(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.post('https://example.com')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_post_with_timeout_none(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.post('https://example.com', timeout=None)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_post_with_timeout(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.post('https://example.com', timeout=5)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_put_default(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.put('https://example.com')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_put_with_timeout_none(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.put('https://example.com', timeout=None)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_put_with_timeout(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.put('https://example.com', timeout=5)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_delete_default(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.delete('https://example.com')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_delete_with_timeout_none(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.delete('https://example.com', timeout=None)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_delete_with_timeout(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.delete('https://example.com', timeout=5)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_patch_default(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.patch('https://example.com')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_patch_with_timeout_none(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.patch('https://example.com', timeout=None)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_patch_with_timeout(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.patch('https://example.com', timeout=5)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_options_default(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.options('https://example.com')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_options_with_timeout_none(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.options('https://example.com', timeout=None)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_options_with_timeout(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.options('https://example.com', timeout=5)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_requests_head_default(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.head('https://example.com')
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_head_with_timeout_none(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.head('https://example.com', timeout=None)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.LOW, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.UNCONTROLLED_RESOURCE_CONSUMPTION, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_requests_head_with_timeout(self):
+ fdata = textwrap.dedent(
+ """
+ import requests
+ requests.head('https://example.com', timeout=5)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_snmp_security_check.py b/tests/unit/plugins/test_snmp_security_check.py
new file mode 100644
index 000000000..829f182e5
--- /dev/null
+++ b/tests/unit/plugins/test_snmp_security_check.py
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class SnmpSecurityCheckTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B508", "B509"])
+
+ def test_communitydata_mpmodel_zero(self):
+ fdata = textwrap.dedent(
+ """
+ from pysnmp import hlapi
+ hlapi.CommunityData('public', mpModel=0)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B508", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_communitydata_mpmodel_one(self):
+ fdata = textwrap.dedent(
+ """
+ from pysnmp import hlapi
+ hlapi.CommunityData('public', mpModel=1)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B508", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_usmuserdata_noauth_nopriv(self):
+ fdata = textwrap.dedent(
+ """
+ from pysnmp import hlapi
+ hlapi.UsmUserData("securityName")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B509", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_usmuserdata_auth_nopriv(self):
+ fdata = textwrap.dedent(
+ """
+ from pysnmp import hlapi
+ hlapi.UsmUserData("securityName", "authName")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual("B509", issue.test_id)
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.CLEARTEXT_TRANSMISSION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_usmuserdata_auth_priv(self):
+ fdata = textwrap.dedent(
+ """
+ from pysnmp import hlapi
+ hlapi.UsmUserData("securityName", "authName", "privName")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_ssh_no_host_key_verification.py b/tests/unit/plugins/test_ssh_no_host_key_verification.py
new file mode 100644
index 000000000..86a7b3eb9
--- /dev/null
+++ b/tests/unit/plugins/test_ssh_no_host_key_verification.py
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class SshNoHostKeyVerificationTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B507"])
+
+ def test_reject_policy(self):
+ fdata = textwrap.dedent(
+ """
+ from paramiko import client
+ ssh_client = client.SSHClient()
+ ssh_client.set_missing_host_key_policy(client.RejectPolicy)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_auto_add_policy(self):
+ fdata = textwrap.dedent(
+ """
+ from paramiko import client
+ ssh_client = client.SSHClient()
+ ssh_client.set_missing_host_key_policy(client.AutoAddPolicy)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_warning_policy(self):
+ fdata = textwrap.dedent(
+ """
+ from paramiko import client
+ ssh_client = client.SSHClient()
+ ssh_client.set_missing_host_key_policy(client.WarningPolicy)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.MEDIUM, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_CERT_VALIDATION, issue.cwe.id)
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
diff --git a/tests/unit/plugins/test_try_except_continue.py b/tests/unit/plugins/test_try_except_continue.py
new file mode 100644
index 000000000..7c80ff763
--- /dev/null
+++ b/tests/unit/plugins/test_try_except_continue.py
@@ -0,0 +1,154 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class TryExceptContinueTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B112"])
+
+ def test_try_except_continue(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except:
+ continue
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([4, 5], issue.linerange)
+ else:
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_try_except_exception_continue(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except Exception:
+ continue
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([4, 5], issue.linerange)
+ else:
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_try_multi_except_pass(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except ZeroDivisionError:
+ a = 2
+ except Exception:
+ continue
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(6, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([6, 7], issue.linerange)
+ else:
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_try_except_continue_check_typed_exception_false(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except ZeroDivisionError:
+ continue
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_try_except_continue_check_typed_exception_true(self):
+ test = next(
+ x
+ for x in self.b_manager.b_ts.tests["ExceptHandler"]
+ if x.__name__ == "try_except_continue"
+ )
+ test._config = {"check_typed_exception": True}
+
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except ZeroDivisionError:
+ continue
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([4, 5], issue.linerange)
+ else:
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_try_except_no_continue(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except:
+ a = 2
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_try_except_silly(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except:
+ continue
+ a = 2
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_try_except_pass.py b/tests/unit/plugins/test_try_except_pass.py
new file mode 100644
index 000000000..548636d0b
--- /dev/null
+++ b/tests/unit/plugins/test_try_except_pass.py
@@ -0,0 +1,155 @@
+# SPDX-License-Identifier: Apache-2.0
+import sys
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class TryExceptPassTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B110"])
+
+ def test_try_except_pass(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except:
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([4, 5], issue.linerange)
+ else:
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_try_except_exception_pass(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except Exception:
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([4, 5], issue.linerange)
+ else:
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_try_multi_except_pass(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except ZeroDivisionError:
+ a = 2
+ except Exception:
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(6, issue.lineno)
+
+ if sys.version_info >= (3, 8):
+ self.assertEqual([6, 7], issue.linerange)
+ else:
+ self.assertEqual([6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_try_except_pass_check_typed_exception_false(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except ZeroDivisionError:
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_try_except_pass_check_typed_exception_true(self):
+ test = next(
+ x
+ for x in self.b_manager.b_ts.tests["ExceptHandler"]
+ if x.__name__ == "try_except_pass"
+ )
+ test._config = {"check_typed_exception": True}
+
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except ZeroDivisionError:
+ pass
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.LOW, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.IMPROPER_CHECK_OF_EXCEPT_COND, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ if sys.version_info >= (3, 8):
+ self.assertEqual([4, 5], issue.linerange)
+ else:
+ self.assertEqual([4], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_try_except_no_pass(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except:
+ a = 2
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_try_except_silly(self):
+ fdata = textwrap.dedent(
+ """
+ try:
+ a = 1
+ except:
+ pass
+ a = 2
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_weak_cryptographic_key.py b/tests/unit/plugins/test_weak_cryptographic_key.py
new file mode 100644
index 000000000..d93682972
--- /dev/null
+++ b/tests/unit/plugins/test_weak_cryptographic_key.py
@@ -0,0 +1,438 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class WeakCryptographicKeyTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B505"])
+
+ def test_cryptography_dsa_2048(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import dsa
+ dsa.generate_private_key(key_size=2048,
+ backend=backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_cryptography_ec_secp384r1(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import ec
+ ec.generate_private_key(curve=ec.SECP384R1,
+ backend=backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_cryptography_rsa_2048(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import rsa
+ rsa.generate_private_key(public_exponent=65537,
+ key_size=2048,
+ backend=backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_pycrypto_dsa_2048(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.PublicKey import DSA as pycrypto_dsa
+ pycrypto_dsa.generate(bits=2048)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_pycrypto_rsa_2048(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.PublicKey import RSA as pycrypto_rsa
+ pycrypto_rsa.generate(bits=2048)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_pycryptodomex_dsa_2048(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.PublicKey import DSA as pycryptodomex_dsa
+ pycryptodomex_dsa.generate(bits=2048)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_pycryptodomex_rsa_2048(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.PublicKey import RSA as pycryptodomex_rsa
+ pycryptodomex_rsa.generate(bits=2048)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_cryptography_dsa_4096(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import dsa
+ dsa.generate_private_key(4096,
+ backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_cryptography_ec_secp256k1(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import ec
+ ec.generate_private_key(ec.SECP256K1,
+ backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_cryptography_rsa_4096(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import rsa
+ rsa.generate_private_key(3,
+ 4096,
+ backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_pycrypto_dsa_4096(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.PublicKey import DSA as pycrypto_dsa
+ pycrypto_dsa.generate(4096)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_pycrypto_rsa_4096(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.PublicKey import RSA as pycrypto_rsa
+ pycrypto_rsa.generate(4096)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_pycryptodomex_dsa_4096(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.PublicKey import DSA as pycryptodomex_dsa
+ pycryptodomex_dsa.generate(4096)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_pycryptodomex_rsa_4096(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.PublicKey import RSA as pycryptodomex_rsa
+ pycryptodomex_rsa.generate(4096)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_cryptography_dsa_1024(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import dsa
+ dsa.generate_private_key(key_size=1024,
+ backend=backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4, 5], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptography_ec_sect163r2(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import ec
+ ec.generate_private_key(curve=ec.SECT163R2,
+ backend=backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4, 5], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptography_rsa_1024(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import rsa
+ rsa.generate_private_key(public_exponent=65537,
+ key_size=1024,
+ backend=backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4, 5, 6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pycrypto_dsa_1024(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.PublicKey import DSA as pycrypto_dsa
+ pycrypto_dsa.generate(bits=1024)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pycrypto_rsa_1024(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.PublicKey import RSA as pycrypto_rsa
+ pycrypto_rsa.generate(bits=1024)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pycryptodomex_dsa_1024(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.PublicKey import DSA as pycryptodomex_dsa
+ pycryptodomex_dsa.generate(bits=1024)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pycryptodomex_rsa_1024(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.PublicKey import RSA as pycryptodomex_rsa
+ pycryptodomex_rsa.generate(bits=1024)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptography_dsa_512(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import dsa
+ dsa.generate_private_key(512,
+ backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4, 5], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptography_rsa_512(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import rsa
+ rsa.generate_private_key(3,
+ 512,
+ backends.default_backend())
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(4, issue.lineno)
+ self.assertEqual([4, 5, 6], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pycrypto_dsa_512(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.PublicKey import DSA as pycrypto_dsa
+ pycrypto_dsa.generate(512)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pycrypto_rsa_512(self):
+ fdata = textwrap.dedent(
+ """
+ from Crypto.PublicKey import RSA as pycrypto_rsa
+ pycrypto_rsa.generate(512)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pycryptodomex_dsa_512(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.PublicKey import DSA as pycryptodomex_dsa
+ pycryptodomex_dsa.generate(512)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_pycryptodomex_rsa_512(self):
+ fdata = textwrap.dedent(
+ """
+ from Cryptodome.PublicKey import RSA as pycryptodomex_rsa
+ pycryptodomex_rsa.generate(512)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.HIGH, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(
+ b_issue.Cwe.INADEQUATE_ENCRYPTION_STRENGTH, issue.cwe.id
+ )
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_cryptography_ec_unknown_curve(self):
+ fdata = textwrap.dedent(
+ """
+ from cryptography.hazmat import backends
+ from cryptography.hazmat.primitives.asymmetric import ec
+ ec.generate_private_key(
+ curve=curves[self.curve]['create'](self.size),
+ backend=backends.default_backend()
+ )
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
diff --git a/tests/unit/plugins/test_yaml_load.py b/tests/unit/plugins/test_yaml_load.py
new file mode 100644
index 000000000..c16c4e2ae
--- /dev/null
+++ b/tests/unit/plugins/test_yaml_load.py
@@ -0,0 +1,122 @@
+# SPDX-License-Identifier: Apache-2.0
+import textwrap
+
+import bandit
+from bandit.core import issue as b_issue
+from tests.unit.plugins import base_test_case
+
+
+class YamlLoadTests(base_test_case.BaseTestCase):
+ def setUp(self):
+ super().setUp(["B506"])
+
+ def test_load_with_default_loader(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ yaml.load("{}")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_INPUT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_load_with_safeloader(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ yaml.load("{}", Loader=yaml.SafeLoader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_load_with_csafeloader(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ yaml.load("{}", Loader=yaml.CSafeLoader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_load_with_unsafe_loader(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ yaml.load("{}", Loader=yaml.Loader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(1, len(self.visitor.tester.results))
+ issue = self.visitor.tester.results[0]
+ self.assertEqual(bandit.MEDIUM, issue.severity)
+ self.assertEqual(bandit.HIGH, issue.confidence)
+ self.assertEqual(b_issue.Cwe.IMPROPER_INPUT_VALIDATION, issue.cwe.id)
+ self.assertEqual(3, issue.lineno)
+ self.assertEqual([3], issue.linerange)
+ self.assertEqual(0, issue.col_offset)
+
+ def test_safe_load(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ yaml.safe_load("{}")
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_load_no_import(self):
+ fdata = 'yaml.load("{}")'
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_load_safeloader(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ from yaml import SafeLoader
+ yaml.load("{}", SafeLoader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_load_yaml_safeloader(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ yaml.load("{}", yaml.SafeLoader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_load_csafeloader(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ from yaml import CSafeLoader
+ yaml.load("{}", CSafeLoader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))
+
+ def test_load_yaml_csafeloader(self):
+ fdata = textwrap.dedent(
+ """
+ import yaml
+ yaml.load("{}", yaml.CSafeLoader)
+ """
+ )
+ self.visitor.process(fdata)
+ self.assertEqual(0, len(self.visitor.tester.results))