From 51f048e34272ad82a6dfb5ad332fc8de823703ac Mon Sep 17 00:00:00 2001 From: noliverio Date: Sun, 19 Dec 2021 23:15:11 -0500 Subject: [PATCH 1/3] Check for hardcoded passwords in class attributes B105:hardcoded_password_string currently throws an error for string literal variables, dictionary keys, and comparisons which look like passwords, but does not create an error for class attributes which look like passwords. For example password = "mypassword" and password == "mypassword" would create an error, but my_object.password = "mypassword", and my_object.password == "mypassword" would not. This behavior is unintuitive. Resolves #759 --- bandit/plugins/general_hardcoded_password.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bandit/plugins/general_hardcoded_password.py b/bandit/plugins/general_hardcoded_password.py index 4a3db14a1..28bb37cd9 100644 --- a/bandit/plugins/general_hardcoded_password.py +++ b/bandit/plugins/general_hardcoded_password.py @@ -36,6 +36,7 @@ def hardcoded_password_string(context): - assigned to a variable that looks like a password - assigned to a dict key that looks like a password + - assigned to a class attribute that looks like a password - used in a comparison with a variable that looks like a password Variables are considered to look like a password if they have match any one @@ -79,6 +80,9 @@ def hardcoded_password_string(context): for targ in node._bandit_parent.targets: if isinstance(targ, ast.Name) and RE_CANDIDATES.search(targ.id): return _report(node.s) + elif isinstance(targ, ast.Attribute) \ + and RE_CANDIDATES.search(targ.attr): + return _report(node.s) elif (isinstance(node._bandit_parent, ast.Subscript) and RE_CANDIDATES.search(node.s)): @@ -105,6 +109,10 @@ def hardcoded_password_string(context): if RE_CANDIDATES.search(comp.left.id): if isinstance(comp.comparators[0], ast.Str): return _report(comp.comparators[0].s) + elif isinstance(comp.left, ast.Attribute): + if RE_CANDIDATES.search(comp.left.attr): + if isinstance(comp.comparators[0], ast.Str): + return _report(comp.comparators[0].s) @test.checks('Call') From d038529836d19de025038d96c0b5325d6d988387 Mon Sep 17 00:00:00 2001 From: noliverio Date: Tue, 21 Dec 2021 23:31:32 -0500 Subject: [PATCH 2/3] Add tests for hardcoded passwords in classes --- examples/hardcoded-passwords.py | 12 ++++++++++++ tests/functional/test_functional.py | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/examples/hardcoded-passwords.py b/examples/hardcoded-passwords.py index d7cbdc553..2b501c725 100644 --- a/examples/hardcoded-passwords.py +++ b/examples/hardcoded-passwords.py @@ -1,3 +1,8 @@ +# Possible hardcoded password: 'class_password' +# Severity: Low Confidence: Medium +class SomeClass: + password = "class_password" + # Possible hardcoded password: 'Admin' # Severity: Low Confidence: Medium def someFunction(user, password="Admin"): @@ -21,6 +26,13 @@ def NoMatch2(password): if password == "ajklawejrkl42348swfgkg": print("Nice password!") +def noMatchObject(): + obj = SomeClass() + # Possible hardcoded password: 'this cool password' + # Severity: Low Confidence: Medium + if obj.password == "this cool password": + print(obj.password) + # Possible hardcoded password: 'blerg' # Severity: Low Confidence: Medium def doLogin(password="blerg"): diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py index 173d4d67b..af8e91f33 100644 --- a/tests/functional/test_functional.py +++ b/tests/functional/test_functional.py @@ -158,8 +158,8 @@ def test_exec(self): def test_hardcoded_passwords(self): '''Test for hard-coded passwords.''' expect = { - 'SEVERITY': {'UNDEFINED': 0, 'LOW': 12, 'MEDIUM': 0, 'HIGH': 0}, - 'CONFIDENCE': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 12, 'HIGH': 0} + '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) From 45d726bbcc598cfc41cbcb102ee2c5159f935a15 Mon Sep 17 00:00:00 2001 From: Eric Brown Date: Mon, 7 Feb 2022 18:40:31 -0800 Subject: [PATCH 3/3] Update general_hardcoded_password.py --- bandit/plugins/general_hardcoded_password.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bandit/plugins/general_hardcoded_password.py b/bandit/plugins/general_hardcoded_password.py index ef1d8cb04..9a162b485 100644 --- a/bandit/plugins/general_hardcoded_password.py +++ b/bandit/plugins/general_hardcoded_password.py @@ -85,8 +85,9 @@ def hardcoded_password_string(context): for targ in node._bandit_parent.targets: if isinstance(targ, ast.Name) and RE_CANDIDATES.search(targ.id): return _report(node.s) - elif isinstance(targ, ast.Attribute) \ - and RE_CANDIDATES.search(targ.attr): + elif isinstance(targ, ast.Attribute) and RE_CANDIDATES.search( + targ.attr + ): return _report(node.s) elif isinstance(