From 78643c5b2173596b8ae2bd96e1c2e56c0b38560a Mon Sep 17 00:00:00 2001 From: "Dave Walker (Daviey)" Date: Sun, 12 Jul 2015 21:11:44 +0100 Subject: [PATCH] Install word_list, raise exception if cannot find Previously, the default bandit.yaml config file had an entry for a relative word-list which is only really useful if running bandit from git, as the path is both relative but also the default word-list is not installed by the bandit python package. If the word-list from the config cannot be found, the current behavior is to silently continue with an empty set, meaning that this test does not function at all - giving a false sense of assurance. This change installs the default word_list to: - /usr/local/share/bandit/wordlist/default-passwords The config file now supports "(site_data_dir)" for substitution, which is replaced by distro standard site_data locations (including /usr/local and /usr). The first substitution attempted is still relative to the pwd, to allow the current working tree (and unit tests) to function). Crucially, this change now raises an exception if the declared word-list cannot be found. Closes-Bug: #1451575 Signed-off-by: Dave Walker (Daviey) Change-Id: Ia090ee6b16866d374191c03de55529fbd6a10c99 --- bandit/config/bandit.yaml | 4 +- bandit/plugins/general_hardcoded_password.py | 45 ++++++++++++++++---- requirements.txt | 1 + setup.cfg | 3 ++ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/bandit/config/bandit.yaml b/bandit/config/bandit.yaml index cc348875..0d3d4322 100644 --- a/bandit/config/bandit.yaml +++ b/bandit/config/bandit.yaml @@ -107,7 +107,9 @@ blacklist_imports: message: "Consider possible security implications associated with {module} module." hardcoded_password: - word_list: "wordlist/default-passwords" + # Support for full path, relative path and special "%(site_data_dir)s" + # substitution (/usr/{local}/share) + word_list: "%(site_data_dir)s/wordlist/default-passwords" ssl_with_bad_version: bad_protocol_versions: diff --git a/bandit/plugins/general_hardcoded_password.py b/bandit/plugins/general_hardcoded_password.py index f1fb0b3e..4bf04c48 100644 --- a/bandit/plugins/general_hardcoded_password.py +++ b/bandit/plugins/general_hardcoded_password.py @@ -14,27 +14,56 @@ # License for the specific language governing permissions and limitations # under the License. +import os.path +import warnings + +from appdirs import site_data_dir + import bandit from bandit.core.test_properties import * +def find_word_list(cfg_word_list_f): + if not isinstance(cfg_word_list_f, str): + return None + try: + cfg_word_list_f % {'site_data_dir': ''} + except TypeError: + return cfg_word_list_f + + site_data_dirs = ['.'] + site_data_dir("bandit", "", + multipath=True).split(':') + for dir in site_data_dirs: + word_list_path = cfg_word_list_f % {'site_data_dir': dir} + if os.path.isfile(word_list_path): + if dir == ".": + warnings.warn("Using relative path for word_list: %s" + % word_list_path) + return word_list_path + + raise RuntimeError("Could not substitute '%(site_data_dir)s' " + "to a path with a valid word_list file") + + @takes_config @checks('Str') def hardcoded_password(context, config): - word_list_file = "" - - # try to read the word list file from config - if(config is not None and 'word_list' in config and - type(config['word_list']) == str): - word_list_file = config['word_list'] - + word_list_file = None word_list = [] + # try to read the word list file from config + if (config is not None and 'word_list' in config): + try: + word_list_file = find_word_list(config['word_list']) + except RuntimeError as e: + warnings.warn(e.message) + return # try to open the word list file and read passwords from it try: f = open(word_list_file, 'r') except (OSError, IOError): - return + raise RuntimeError("Could not open word_list (from config" + " file): %s" % word_list_file) else: for word in f: word_list.append(word.strip()) diff --git a/requirements.txt b/requirements.txt index 3c8725b1..fd0ed15e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +appdirs>=1.3.0 # MIT License PyYAML>=3.1.0 six>=1.9.0 stevedore>=1.5.0 # Apache 2.0 diff --git a/setup.cfg b/setup.cfg index e99df33e..b8fd6df8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,3 +32,6 @@ bandit.formatters = [files] package_data = bandit = config/bandit.yaml +data_files = + bandit = + share/bandit/wordlist/ = wordlist/default-passwords