Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Password #387

Merged
merged 18 commits into from Jan 14, 2019
Merged
23 changes: 14 additions & 9 deletions bandit/plugins/general_hardcoded_password.py
Expand Up @@ -15,14 +15,18 @@
# under the License.

import ast
import re
import sys

import bandit
from bandit.core import test_properties as test


CANDIDATES = set(["password", "pass", "passwd", "pwd", "secret", "token",
"secrete"])
RE_WORDS = "(pas+wo?r?d|pass|pwd|token|secrete?)"
RE_CANDIDATES = re.compile(
'(^{0}$|_{0}_|^{0}_|_{0}$)'.format(RE_WORDS),
re.IGNORECASE
)


def _report(value):
Expand Down Expand Up @@ -84,10 +88,10 @@ def hardcoded_password_string(context):
if isinstance(node.parent, ast.Assign):
# looks for "candidate='some_string'"
for targ in node.parent.targets:
if isinstance(targ, ast.Name) and targ.id in CANDIDATES:
if isinstance(targ, ast.Name) and RE_CANDIDATES.search(targ.id):
return _report(node.s)

elif isinstance(node.parent, ast.Index) and node.s in CANDIDATES:
elif isinstance(node.parent, ast.Index) and RE_CANDIDATES.search(node.s):
# looks for "dict[candidate]='some_string'"
# assign -> subscript -> index -> string
assign = node.parent.parent.parent
Expand All @@ -98,9 +102,10 @@ def hardcoded_password_string(context):
elif isinstance(node.parent, ast.Compare):
# looks for "candidate == 'some_string'"
comp = node.parent
if isinstance(comp.left, ast.Name) and comp.left.id in CANDIDATES:
if isinstance(comp.comparators[0], ast.Str):
return _report(comp.comparators[0].s)
if isinstance(comp.left, ast.Name):
if RE_CANDIDATES.search(comp.left.id):
if isinstance(comp.comparators[0], ast.Str):
return _report(comp.comparators[0].s)


@test.checks('Call')
Expand Down Expand Up @@ -150,7 +155,7 @@ def hardcoded_password_funcarg(context):
"""
# looks for "function(candidate='some_string')"
for kw in context.node.keywords:
if isinstance(kw.value, ast.Str) and kw.arg in CANDIDATES:
if isinstance(kw.value, ast.Str) and RE_CANDIDATES.search(kw.arg):
return _report(kw.value.s)


Expand Down Expand Up @@ -211,5 +216,5 @@ def hardcoded_password_default(context):
for key, val in zip(context.node.args.args, defs):
if isinstance(key, ast.Name) or isinstance(key, ast.arg):
check = key.arg if sys.version_info.major > 2 else key.id # Py3
if isinstance(val, ast.Str) and check in CANDIDATES:
if isinstance(val, ast.Str) and RE_CANDIDATES.search(check):
ehooo marked this conversation as resolved.
Show resolved Hide resolved
return _report(val.s)
4 changes: 4 additions & 0 deletions examples/hardcoded-passwords.py
Expand Up @@ -22,3 +22,7 @@ def NoMatch3(a, b):
doLogin(password="blerg")
password = "blerg"
d["password"] = "blerg"

EMAIL_PASSWORD = "secret"
email_pwd = 'emails_secret'
my_secret_password_for_email = 'd6s$f9g!j8mg7hw?n&2'
4 changes: 2 additions & 2 deletions tests/functional/test_functional.py
Expand Up @@ -179,8 +179,8 @@ def test_exec(self):
def test_hardcoded_passwords(self):
'''Test for hard-coded passwords.'''
expect = {
'SEVERITY': {'UNDEFINED': 0, 'LOW': 8, 'MEDIUM': 0, 'HIGH': 0},
'CONFIDENCE': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 8, 'HIGH': 0}
'SEVERITY': {'UNDEFINED': 0, 'LOW': 11, 'MEDIUM': 0, 'HIGH': 0},
'CONFIDENCE': {'UNDEFINED': 0, 'LOW': 0, 'MEDIUM': 11, 'HIGH': 0}
}
self.check_example('hardcoded-passwords.py', expect)

Expand Down