diff --git a/bandit/plugins/general_bind_all_interfaces.py b/bandit/plugins/general_bind_all_interfaces.py index 58b840e86..02ab4b0a8 100644 --- a/bandit/plugins/general_bind_all_interfaces.py +++ b/bandit/plugins/general_bind_all_interfaces.py @@ -9,8 +9,8 @@ Binding to all network interfaces can potentially open up a service to traffic on unintended interfaces, that may not be properly documented or secured. This -plugin test looks for a string pattern "0.0.0.0" that may indicate a hardcoded -binding to all network interfaces. +plugin test looks for a string pattern "0.0.0.0" or a bind address of "" that +may indicate a hardcoded binding to all network interfaces. :Example: @@ -22,7 +22,8 @@ Location: ./examples/binding.py:4 3 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 4 s.bind(('0.0.0.0', 31137)) - 5 s.bind(('192.168.0.1', 8080)) + 5 s.bind(('', 31137)) + 6 s.bind(('192.168.0.1', 8080)) .. seealso:: @@ -40,7 +41,7 @@ from bandit.core import test_properties as test -@test.checks("Str") +@test.checks("Str", "Call") @test.test_id("B104") def hardcoded_bind_all_interfaces(context): if context.string_val == "0.0.0.0": # nosec: B104 @@ -50,3 +51,18 @@ def hardcoded_bind_all_interfaces(context): cwe=issue.Cwe.MULTIPLE_BINDS, text="Possible binding to all interfaces.", ) + + if context.call_function_name != "bind": + return + + bind_arg = context.get_call_arg_at_position(0) + if not isinstance(bind_arg, tuple) or not bind_arg: + return + + if bind_arg[0] == "": + return bandit.Issue( + severity=bandit.MEDIUM, + confidence=bandit.MEDIUM, + cwe=issue.Cwe.MULTIPLE_BINDS, + text="Possible binding to all interfaces.", + ) diff --git a/examples/binding.py b/examples/binding.py index fee248702..63ab2a224 100644 --- a/examples/binding.py +++ b/examples/binding.py @@ -2,4 +2,6 @@ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('0.0.0.0', 31137)) +s.bind(('', 31137)) s.bind(('192.168.0.1', 8080)) +s.bind(('127.0.0.1', 8080)) diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py index 08b1c5c5b..1e91f21a4 100644 --- a/tests/functional/test_functional.py +++ b/tests/functional/test_functional.py @@ -110,10 +110,10 @@ def check_metrics(self, example_script, expect): self.assertEqual(expected, m["_totals"][label]) def test_binding(self): - """Test the bind-to-0.0.0.0 example.""" + """Test bind-to-all-interfaces examples.""" expect = { - "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0}, - "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 1, "HIGH": 0}, + "SEVERITY": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 2, "HIGH": 0}, + "CONFIDENCE": {"UNDEFINED": 0, "LOW": 0, "MEDIUM": 2, "HIGH": 0}, } self.check_example("binding.py", expect)