Trivial fixes based on pylint scan
* Constants should be in caps * Redundant ( ) in if statements * Use isinstance instead of type == * Indentation Change-Id: I79fda14112a9dd02fe867f6d850762216e0ca9a1
This commit is contained in:
parent
4bfa1b69be
commit
3be3ca4de0
@ -38,7 +38,7 @@ bandit_args = sys.argv[1:]
|
||||
baseline_tmp_file = '_bandit_baseline_run.json_'
|
||||
current_commit = None
|
||||
default_output_format = 'terminal'
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
repo = None
|
||||
report_basename = 'bandit_baseline_result'
|
||||
valid_baseline_formats = ['txt', 'html', 'json']
|
||||
@ -65,17 +65,17 @@ def main():
|
||||
try:
|
||||
commit = repo.commit()
|
||||
current_commit = commit.hexsha
|
||||
logger.info('Got current commit: [%s]', commit.name_rev)
|
||||
LOG.info('Got current commit: [%s]', commit.name_rev)
|
||||
|
||||
commit = commit.parents[0]
|
||||
parent_commit = commit.hexsha
|
||||
logger.info('Got parent commit: [%s]', commit.name_rev)
|
||||
LOG.info('Got parent commit: [%s]', commit.name_rev)
|
||||
|
||||
except git.GitCommandError:
|
||||
logger.error("Unable to get current or parent commit")
|
||||
LOG.error("Unable to get current or parent commit")
|
||||
sys.exit(2)
|
||||
except IndexError:
|
||||
logger.error("Parent commit not available")
|
||||
LOG.error("Parent commit not available")
|
||||
sys.exit(2)
|
||||
|
||||
# #################### Run Bandit against both commits ####################
|
||||
@ -99,7 +99,7 @@ def main():
|
||||
for step in steps:
|
||||
repo.head.reset(commit=step['commit'], working_tree=True)
|
||||
|
||||
logger.info(step['message'])
|
||||
LOG.info(step['message'])
|
||||
|
||||
bandit_command = ['bandit'] + step['args']
|
||||
|
||||
@ -113,15 +113,15 @@ def main():
|
||||
output = output.decode('utf-8') # subprocess returns bytes
|
||||
|
||||
if return_code not in [0, 1]:
|
||||
logger.error("Error running command: %s\nOutput: %s\n",
|
||||
bandit_args, output)
|
||||
LOG.error("Error running command: %s\nOutput: %s\n",
|
||||
bandit_args, output)
|
||||
|
||||
# #################### Output and exit ####################################
|
||||
# print output or display message about written report
|
||||
if output_format == default_output_format:
|
||||
print(output)
|
||||
else:
|
||||
logger.info("Successfully wrote %s", report_fname)
|
||||
LOG.info("Successfully wrote %s", report_fname)
|
||||
|
||||
# exit with the code the last Bandit run returned
|
||||
sys.exit(return_code)
|
||||
@ -140,14 +140,14 @@ def baseline_setup():
|
||||
|
||||
# #################### Setup logging ##########################################
|
||||
def init_logger():
|
||||
logger.handlers = []
|
||||
LOG.handlers = []
|
||||
log_level = logging.INFO
|
||||
log_format_string = "[%(levelname)7s ] %(message)s"
|
||||
logging.captureWarnings(True)
|
||||
logger.setLevel(log_level)
|
||||
LOG.setLevel(log_level)
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(logging.Formatter(log_format_string))
|
||||
logger.addHandler(handler)
|
||||
LOG.addHandler(handler)
|
||||
|
||||
|
||||
# #################### Perform initialization and validate assumptions ########
|
||||
@ -178,8 +178,7 @@ def initialize():
|
||||
else default_output_format)
|
||||
|
||||
if output_format == default_output_format:
|
||||
logger.info("No output format specified, using %s",
|
||||
default_output_format)
|
||||
LOG.info("No output format specified, using %s", default_output_format)
|
||||
|
||||
# set the report name based on the output format
|
||||
report_fname = "{}.{}".format(report_basename, output_format)
|
||||
@ -189,33 +188,33 @@ def initialize():
|
||||
repo = git.Repo(os.getcwd())
|
||||
|
||||
except git.exc.InvalidGitRepositoryError:
|
||||
logger.error("Bandit baseline must be called from a git project root")
|
||||
LOG.error("Bandit baseline must be called from a git project root")
|
||||
valid = False
|
||||
|
||||
except git.exc.GitCommandNotFound:
|
||||
logger.error("Git command not found")
|
||||
LOG.error("Git command not found")
|
||||
valid = False
|
||||
|
||||
else:
|
||||
if repo.is_dirty():
|
||||
logger.error("Current working directory is dirty and must be "
|
||||
"resolved")
|
||||
LOG.error("Current working directory is dirty and must be "
|
||||
"resolved")
|
||||
valid = False
|
||||
|
||||
# if output format is specified, we need to be able to write the report
|
||||
if output_format != default_output_format and os.path.exists(report_fname):
|
||||
logger.error("File %s already exists, aborting", report_fname)
|
||||
LOG.error("File %s already exists, aborting", report_fname)
|
||||
valid = False
|
||||
|
||||
# Bandit needs to be able to create this temp file
|
||||
if os.path.exists(baseline_tmp_file):
|
||||
logger.error("Temporary file %s needs to be removed prior to running",
|
||||
baseline_tmp_file)
|
||||
LOG.error("Temporary file %s needs to be removed prior to running",
|
||||
baseline_tmp_file)
|
||||
valid = False
|
||||
|
||||
# we must validate -o is not provided, as it will mess up Bandit baseline
|
||||
if '-o' in bandit_args:
|
||||
logger.error("Bandit baseline must not be called with the -o option")
|
||||
LOG.error("Bandit baseline must not be called with the -o option")
|
||||
valid = False
|
||||
|
||||
return (output_format, repo, report_fname) if valid else (None, None, None)
|
||||
|
@ -25,7 +25,7 @@ import yaml
|
||||
from bandit.core import extension_loader
|
||||
|
||||
PROG_NAME = 'bandit_conf_generator'
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
template = """
|
||||
@ -60,14 +60,14 @@ template = """
|
||||
|
||||
|
||||
def init_logger():
|
||||
logger.handlers = []
|
||||
LOG.handlers = []
|
||||
log_level = logging.INFO
|
||||
log_format_string = "[%(levelname)5s]: %(message)s"
|
||||
logging.captureWarnings(True)
|
||||
logger.setLevel(log_level)
|
||||
LOG.setLevel(log_level)
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(logging.Formatter(log_format_string))
|
||||
logger.addHandler(handler)
|
||||
LOG.addHandler(handler)
|
||||
|
||||
|
||||
def parse_args():
|
||||
@ -138,7 +138,7 @@ def main():
|
||||
|
||||
if args.output_file:
|
||||
if os.path.exists(os.path.abspath(args.output_file)):
|
||||
logger.error("File %s already exists, exiting", args.output_file)
|
||||
LOG.error("File %s already exists, exiting", args.output_file)
|
||||
sys.exit(2)
|
||||
|
||||
try:
|
||||
@ -158,9 +158,9 @@ def main():
|
||||
test_list = [tpl.format(t.plugin._test_id, t.name)
|
||||
for t in extension_loader.MANAGER.plugins]
|
||||
|
||||
test_list.extend([tpl.format(k, v['name'])
|
||||
for k, v in six.iteritems(
|
||||
extension_loader.MANAGER.blacklist_by_id)])
|
||||
others = [tpl.format(k, v['name']) for k, v in six.iteritems(
|
||||
extension_loader.MANAGER.blacklist_by_id)]
|
||||
test_list.extend(others)
|
||||
test_list.sort()
|
||||
|
||||
contents = template.format(
|
||||
@ -172,13 +172,13 @@ def main():
|
||||
f.write(contents)
|
||||
|
||||
except IOError:
|
||||
logger.error("Unable to open %s for writing", args.output_file)
|
||||
LOG.error("Unable to open %s for writing", args.output_file)
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Error: %s", e)
|
||||
LOG.error("Error: %s", e)
|
||||
|
||||
else:
|
||||
logger.info("Successfully wrote profile: %s", args.output_file)
|
||||
LOG.info("Successfully wrote profile: %s", args.output_file)
|
||||
|
||||
return 0
|
||||
|
||||
|
@ -29,7 +29,7 @@ from bandit.core import utils
|
||||
|
||||
|
||||
BASE_CONFIG = 'bandit.yaml'
|
||||
logger = logging.getLogger()
|
||||
LOG = logging.getLogger()
|
||||
|
||||
|
||||
def _init_logger(debug=False, log_format=None):
|
||||
@ -38,7 +38,7 @@ def _init_logger(debug=False, log_format=None):
|
||||
:param debug: Whether to enable debug mode
|
||||
:return: An instantiated logging instance
|
||||
'''
|
||||
logger.handlers = []
|
||||
LOG.handlers = []
|
||||
log_level = logging.INFO
|
||||
if debug:
|
||||
log_level = logging.DEBUG
|
||||
@ -51,11 +51,11 @@ def _init_logger(debug=False, log_format=None):
|
||||
|
||||
logging.captureWarnings(True)
|
||||
|
||||
logger.setLevel(log_level)
|
||||
LOG.setLevel(log_level)
|
||||
handler = logging.StreamHandler(sys.stderr)
|
||||
handler.setFormatter(logging.Formatter(log_format_string))
|
||||
logger.addHandler(handler)
|
||||
logger.debug("logging initialized")
|
||||
LOG.addHandler(handler)
|
||||
LOG.debug("logging initialized")
|
||||
|
||||
|
||||
def _get_options_from_ini(ini_path, target):
|
||||
@ -73,15 +73,13 @@ def _get_options_from_ini(ini_path, target):
|
||||
bandit_files.append(os.path.join(root, filename))
|
||||
|
||||
if len(bandit_files) > 1:
|
||||
logger.error('Multiple .bandit files found - scan separately or '
|
||||
'choose one with --ini\n\t%s',
|
||||
', '.join(bandit_files))
|
||||
LOG.error('Multiple .bandit files found - scan separately or '
|
||||
'choose one with --ini\n\t%s', ', '.join(bandit_files))
|
||||
sys.exit(2)
|
||||
|
||||
elif len(bandit_files) == 1:
|
||||
ini_file = bandit_files[0]
|
||||
logger.info('Found project level .bandit file: %s',
|
||||
bandit_files[0])
|
||||
LOG.info('Found project level .bandit file: %s', bandit_files[0])
|
||||
|
||||
if ini_file:
|
||||
return utils.parse_ini_file(ini_file)
|
||||
@ -97,10 +95,10 @@ def _init_extensions():
|
||||
def _log_option_source(arg_val, ini_val, option_name):
|
||||
"""It's useful to show the source of each option."""
|
||||
if arg_val:
|
||||
logger.info("Using command line arg for %s", option_name)
|
||||
LOG.info("Using command line arg for %s", option_name)
|
||||
return arg_val
|
||||
elif ini_val:
|
||||
logger.info("Using .bandit arg for %s", option_name)
|
||||
LOG.info("Using .bandit arg for %s", option_name)
|
||||
return ini_val
|
||||
else:
|
||||
return None
|
||||
@ -120,7 +118,7 @@ def _get_profile(config, profile_name, config_path):
|
||||
profile = profiles.get(profile_name)
|
||||
if profile is None:
|
||||
raise utils.ProfileNotFound(config_path, profile_name)
|
||||
logger.debug("read in legacy profile '%s': %s", profile_name, profile)
|
||||
LOG.debug("read in legacy profile '%s': %s", profile_name, profile)
|
||||
else:
|
||||
profile['include'] = set(config.get_option('tests') or [])
|
||||
profile['exclude'] = set(config.get_option('skips') or [])
|
||||
@ -130,10 +128,10 @@ def _get_profile(config, profile_name, config_path):
|
||||
def _log_info(args, profile):
|
||||
inc = ",".join([t for t in profile['include']]) or "None"
|
||||
exc = ",".join([t for t in profile['exclude']]) or "None"
|
||||
logger.info("profile include tests: %s", inc)
|
||||
logger.info("profile exclude tests: %s", exc)
|
||||
logger.info("cli include tests: %s", args.tests)
|
||||
logger.info("cli exclude tests: %s", args.skips)
|
||||
LOG.info("profile include tests: %s", inc)
|
||||
LOG.info("profile exclude tests: %s", exc)
|
||||
LOG.info("cli include tests: %s", args.tests)
|
||||
LOG.info("cli exclude tests: %s", args.skips)
|
||||
|
||||
|
||||
def main():
|
||||
@ -265,7 +263,7 @@ def main():
|
||||
try:
|
||||
b_conf = b_config.BanditConfig(config_file=args.config_file)
|
||||
except utils.ConfigError as e:
|
||||
logger.error(e)
|
||||
LOG.error(e)
|
||||
sys.exit(2)
|
||||
|
||||
# Handle .bandit files in projects to pass cmdline args from file
|
||||
@ -297,7 +295,7 @@ def main():
|
||||
extension_mgr.validate_profile(profile)
|
||||
|
||||
except (utils.ProfileNotFound, ValueError) as e:
|
||||
logger.error(e)
|
||||
LOG.error(e)
|
||||
sys.exit(2)
|
||||
|
||||
b_mgr = b_manager.BanditManager(b_conf, args.agg_type, args.debug,
|
||||
@ -310,32 +308,32 @@ def main():
|
||||
data = bl.read()
|
||||
b_mgr.populate_baseline(data)
|
||||
except IOError:
|
||||
logger.warning("Could not open baseline report: %s", args.baseline)
|
||||
LOG.warning("Could not open baseline report: %s", args.baseline)
|
||||
sys.exit(2)
|
||||
|
||||
if args.output_format not in baseline_formatters:
|
||||
logger.warning('Baseline must be used with one of the following '
|
||||
'formats: ' + str(baseline_formatters))
|
||||
LOG.warning('Baseline must be used with one of the following '
|
||||
'formats: ' + str(baseline_formatters))
|
||||
sys.exit(2)
|
||||
|
||||
if args.output_format != "json":
|
||||
if args.config_file:
|
||||
logger.info("using config: %s", args.config_file)
|
||||
LOG.info("using config: %s", args.config_file)
|
||||
|
||||
logger.info("running on Python %d.%d.%d", sys.version_info.major,
|
||||
sys.version_info.minor, sys.version_info.micro)
|
||||
LOG.info("running on Python %d.%d.%d", sys.version_info.major,
|
||||
sys.version_info.minor, sys.version_info.micro)
|
||||
|
||||
# initiate file discovery step within Bandit Manager
|
||||
b_mgr.discover_files(args.targets, args.recursive, args.excluded_paths)
|
||||
|
||||
if not b_mgr.b_ts.tests:
|
||||
logger.error('No tests would be run, please check the profile.')
|
||||
LOG.error('No tests would be run, please check the profile.')
|
||||
sys.exit(2)
|
||||
|
||||
# initiate execution of tests within Bandit Manager
|
||||
b_mgr.run_tests()
|
||||
logger.debug(b_mgr.b_ma)
|
||||
logger.debug(b_mgr.metrics)
|
||||
LOG.debug(b_mgr.b_ma)
|
||||
LOG.debug(b_mgr.metrics)
|
||||
|
||||
# trigger output of results by Bandit Manager
|
||||
sev_level = constants.RANKING[args.severity - 1]
|
||||
|
@ -24,7 +24,7 @@ from bandit.core import extension_loader
|
||||
from bandit.core import utils
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BanditConfig():
|
||||
@ -167,8 +167,8 @@ class BanditConfig():
|
||||
bad_imports_list.append(val)
|
||||
|
||||
if bad_imports_list or bad_calls_list:
|
||||
logger.warning('Legacy blacklist data found in config, '
|
||||
'overriding data plugins')
|
||||
LOG.warning('Legacy blacklist data found in config, overriding '
|
||||
'data plugins')
|
||||
return bad_calls_list, bad_imports_list
|
||||
|
||||
def convert_legacy_blacklist_tests(self, profiles, bad_imports, bad_calls):
|
||||
@ -235,9 +235,8 @@ class BanditConfig():
|
||||
|
||||
# show deprecation message
|
||||
if legacy:
|
||||
logger.warn("Config file '%s' contains deprecated legacy "
|
||||
"config data. Please consider upgrading to "
|
||||
"the new config format. The tool "
|
||||
"'bandit-config-generator' can help you with "
|
||||
"this. Support for legacy configs will be removed "
|
||||
"in a future bandit version.", path)
|
||||
LOG.warn("Config file '%s' contains deprecated legacy config "
|
||||
"data. Please consider upgrading to the new config "
|
||||
"format. The tool 'bandit-config-generator' can help you "
|
||||
"with this. Support for legacy configs will be removed "
|
||||
"in a future bandit version.", path)
|
||||
|
@ -103,10 +103,8 @@ class Context():
|
||||
|
||||
:return: A dictionary of keyword parameters for a call as strings
|
||||
'''
|
||||
if (
|
||||
'call' in self._context and
|
||||
hasattr(self._context['call'], 'keywords')
|
||||
):
|
||||
if ('call' in self._context and
|
||||
hasattr(self._context['call'], 'keywords')):
|
||||
return_dict = {}
|
||||
for li in self._context['call'].keywords:
|
||||
if hasattr(li.value, 'attr'):
|
||||
@ -152,7 +150,7 @@ class Context():
|
||||
'''Get escaped value of the object.
|
||||
|
||||
Turn the value of a string or bytes object into byte sequence with
|
||||
unknown, control, and \ characters escaped.
|
||||
unknown, control, and \\ characters escaped.
|
||||
|
||||
This function should be used when looking for a known sequence in a
|
||||
potentially badly encoded string in the code.
|
||||
@ -298,11 +296,9 @@ class Context():
|
||||
:param position_num: The index of the argument to return the value for
|
||||
:return: Value of the argument at the specified position if it exists
|
||||
'''
|
||||
if (
|
||||
'call' in self._context and
|
||||
hasattr(self._context['call'], 'args') and
|
||||
position_num < len(self._context['call'].args)
|
||||
):
|
||||
if ('call' in self._context and
|
||||
hasattr(self._context['call'], 'args') and
|
||||
position_num < len(self._context['call'].args)):
|
||||
return self._get_literal_value(
|
||||
self._context['call'].args[position_num]
|
||||
)
|
||||
@ -315,10 +311,7 @@ class Context():
|
||||
:param module: The module name to look for
|
||||
:return: True if the module is found, False otherwise
|
||||
'''
|
||||
if 'module' in self._context and self._context['module'] == module:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return 'module' in self._context and self._context['module'] == module
|
||||
|
||||
def is_module_imported_exact(self, module):
|
||||
'''Check if a specified module has been imported; only exact matches.
|
||||
@ -326,10 +319,8 @@ class Context():
|
||||
:param module: The module name to look for
|
||||
:return: True if the module is found, False otherwise
|
||||
'''
|
||||
if 'imports' in self._context and module in self._context['imports']:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return ('imports' in self._context and
|
||||
module in self._context['imports'])
|
||||
|
||||
def is_module_imported_like(self, module):
|
||||
'''Check if a specified module has been imported
|
||||
|
@ -15,7 +15,7 @@
|
||||
# under the License.
|
||||
|
||||
# where our docs are hosted
|
||||
base_url = 'http://docs.openstack.org/developer/bandit/'
|
||||
BASE_URL = 'http://docs.openstack.org/developer/bandit/'
|
||||
|
||||
|
||||
def get_url(bid):
|
||||
@ -26,7 +26,7 @@ def get_url(bid):
|
||||
|
||||
info = extension_loader.MANAGER.plugins_by_id.get(bid, None)
|
||||
if info is not None:
|
||||
return base_url + ('plugins/%s.html' % info.plugin.__name__)
|
||||
return BASE_URL + ('plugins/%s.html' % info.plugin.__name__)
|
||||
|
||||
info = extension_loader.MANAGER.blacklist_by_id.get(bid, None)
|
||||
if info is not None:
|
||||
@ -38,6 +38,6 @@ def get_url(bid):
|
||||
ext = template.format(
|
||||
kind='imports', id=info['id'], name=info['name'])
|
||||
|
||||
return base_url + ext.lower()
|
||||
return BASE_URL + ext.lower()
|
||||
|
||||
return base_url # no idea, give the docs main page
|
||||
return BASE_URL # no idea, give the docs main page
|
||||
|
@ -17,11 +17,11 @@
|
||||
from __future__ import division
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from bandit.core import constants
|
||||
import linecache
|
||||
|
||||
from six import moves
|
||||
|
||||
import linecache
|
||||
from bandit.core import constants
|
||||
|
||||
|
||||
class Issue(object):
|
||||
|
@ -31,7 +31,7 @@ from bandit.core import node_visitor as b_node_visitor
|
||||
from bandit.core import test_set as b_test_set
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BanditManager():
|
||||
@ -39,7 +39,7 @@ class BanditManager():
|
||||
scope = []
|
||||
|
||||
def __init__(self, config, agg_type, debug=False, verbose=False,
|
||||
profile={}, ignore_nosec=False):
|
||||
profile=None, ignore_nosec=False):
|
||||
'''Get logger, config, AST handler, and result store ready
|
||||
|
||||
:param config: config options object
|
||||
@ -53,6 +53,8 @@ class BanditManager():
|
||||
'''
|
||||
self.debug = debug
|
||||
self.verbose = verbose
|
||||
if not profile:
|
||||
profile = {}
|
||||
self.ignore_nosec = ignore_nosec
|
||||
self.b_conf = config
|
||||
self.files_list = []
|
||||
@ -86,7 +88,7 @@ class BanditManager():
|
||||
jdata = json.loads(data)
|
||||
items = [issue.issue_from_dict(j) for j in jdata["results"]]
|
||||
except Exception as e:
|
||||
logger.warning("Failed to load baseline data: %s", e)
|
||||
LOG.warning("Failed to load baseline data: %s", e)
|
||||
self.baseline = items
|
||||
|
||||
def filter_results(self, sev_filter, conf_filter):
|
||||
@ -181,8 +183,8 @@ class BanditManager():
|
||||
files_list.update(new_files)
|
||||
excluded_files.update(newly_excluded)
|
||||
else:
|
||||
logger.warning("Skipping directory (%s), use -r flag to "
|
||||
"scan contents", fname)
|
||||
LOG.warning("Skipping directory (%s), use -r flag to "
|
||||
"scan contents", fname)
|
||||
|
||||
else:
|
||||
# if the user explicitly mentions a file on command line,
|
||||
@ -212,7 +214,7 @@ class BanditManager():
|
||||
new_files_list = list(self.files_list)
|
||||
|
||||
for count, fname in enumerate(self.files_list):
|
||||
logger.debug("working on file : %s", fname)
|
||||
LOG.debug("working on file : %s", fname)
|
||||
|
||||
if len(self.files_list) > self.progress:
|
||||
# is it time to update the progress indicator?
|
||||
@ -247,17 +249,17 @@ class BanditManager():
|
||||
))
|
||||
new_files_list.remove(fname)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
LOG.error(
|
||||
"Exception occurred when executing tests against "
|
||||
"{0}. Run \"bandit --debug {0}\" to see the full "
|
||||
"traceback.".format(fname)
|
||||
"%s. Run \"bandit --debug %s\" to see the full "
|
||||
"traceback.", fname, fname
|
||||
)
|
||||
self.skipped.append(
|
||||
(fname, 'exception while scanning file')
|
||||
)
|
||||
new_files_list.remove(fname)
|
||||
logger.debug(" Exception string: %s", e)
|
||||
logger.debug(
|
||||
LOG.debug(" Exception string: %s", e)
|
||||
LOG.debug(
|
||||
" Exception traceback: %s",
|
||||
traceback.format_exc()
|
||||
)
|
||||
@ -294,8 +296,10 @@ class BanditManager():
|
||||
return score
|
||||
|
||||
|
||||
def _get_files_from_dir(files_dir, included_globs=['*.py'],
|
||||
def _get_files_from_dir(files_dir, included_globs=None,
|
||||
excluded_path_strings=None):
|
||||
if not included_globs:
|
||||
included_globs = ['*.py']
|
||||
if not excluded_path_strings:
|
||||
excluded_path_strings = []
|
||||
|
||||
|
@ -19,13 +19,16 @@ import collections
|
||||
import logging
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BanditMetaAst():
|
||||
|
||||
nodes = collections.OrderedDict()
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def add_node(self, node, parent_id, depth):
|
||||
'''Add a node to the AST node collection
|
||||
|
||||
@ -35,7 +38,7 @@ class BanditMetaAst():
|
||||
:return: -
|
||||
'''
|
||||
node_id = hex(id(node))
|
||||
logger.debug('adding node : %s [%s]', node_id, depth)
|
||||
LOG.debug('adding node : %s [%s]', node_id, depth)
|
||||
self.nodes[node_id] = {
|
||||
'raw': node, 'parent_id': parent_id, 'depth': depth
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ from bandit.core import tester as b_tester
|
||||
from bandit.core import utils as b_utils
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BanditNodeVisitor(object):
|
||||
@ -49,10 +49,10 @@ class BanditNodeVisitor(object):
|
||||
try:
|
||||
self.namespace = b_utils.get_module_qualname_from_path(fname)
|
||||
except b_utils.InvalidModulePath:
|
||||
logger.info('Unable to find qualified name for module: %s',
|
||||
self.fname)
|
||||
LOG.info('Unable to find qualified name for module: %s',
|
||||
self.fname)
|
||||
self.namespace = ""
|
||||
logger.debug('Module qualified name: %s', self.namespace)
|
||||
LOG.debug('Module qualified name: %s', self.namespace)
|
||||
self.metrics = metrics
|
||||
|
||||
def visit_ClassDef(self, node):
|
||||
@ -184,14 +184,14 @@ class BanditNodeVisitor(object):
|
||||
self.context['import_aliases'] = self.import_aliases
|
||||
|
||||
if self.debug:
|
||||
logger.debug(ast.dump(node))
|
||||
LOG.debug(ast.dump(node))
|
||||
self.metaast.add_node(node, '', self.depth)
|
||||
|
||||
if hasattr(node, 'lineno'):
|
||||
self.context['lineno'] = node.lineno
|
||||
|
||||
if node.lineno in self.nosec_lines:
|
||||
logger.debug("skipped, nosec")
|
||||
LOG.debug("skipped, nosec")
|
||||
self.metrics.note_nosec()
|
||||
return False
|
||||
|
||||
@ -200,10 +200,10 @@ class BanditNodeVisitor(object):
|
||||
self.context['filename'] = self.fname
|
||||
|
||||
self.seen += 1
|
||||
logger.debug("entering: %s %s [%s]", hex(id(node)), type(node),
|
||||
self.depth)
|
||||
LOG.debug("entering: %s %s [%s]", hex(id(node)), type(node),
|
||||
self.depth)
|
||||
self.depth += 1
|
||||
logger.debug(self.context)
|
||||
LOG.debug(self.context)
|
||||
return True
|
||||
|
||||
def visit(self, node):
|
||||
@ -212,14 +212,14 @@ class BanditNodeVisitor(object):
|
||||
visitor = getattr(self, method, None)
|
||||
if visitor is not None:
|
||||
if self.debug:
|
||||
logger.debug("%s called (%s)", method, ast.dump(node))
|
||||
LOG.debug("%s called (%s)", method, ast.dump(node))
|
||||
visitor(node)
|
||||
else:
|
||||
self.update_scores(self.tester.run_tests(self.context, name))
|
||||
|
||||
def post_visit(self, node):
|
||||
self.depth -= 1
|
||||
logger.debug("%s\texiting : %s", self.depth, hex(id(node)))
|
||||
LOG.debug("%s\texiting : %s", self.depth, hex(id(node)))
|
||||
|
||||
# HACK(tkelsey): this is needed to clean up post-recursion stuff that
|
||||
# gets setup in the visit methods for these node types.
|
||||
|
@ -18,7 +18,7 @@ import logging
|
||||
|
||||
from bandit.core import utils
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def checks(*args):
|
||||
@ -28,8 +28,8 @@ def checks(*args):
|
||||
func._checks = []
|
||||
func._checks.extend(utils.check_ast_node(a) for a in args)
|
||||
|
||||
logger.debug('checks() decorator executed')
|
||||
logger.debug(' func._checks: %s', func._checks)
|
||||
LOG.debug('checks() decorator executed')
|
||||
LOG.debug(' func._checks: %s', func._checks)
|
||||
return func
|
||||
return wrapper
|
||||
|
||||
@ -79,8 +79,7 @@ def accepts_baseline(*args):
|
||||
if not hasattr(func, '_accepts_baseline'):
|
||||
func._accepts_baseline = True
|
||||
|
||||
logger.debug('accepts_baseline() decorator executed on %s',
|
||||
func.__name__)
|
||||
LOG.debug('accepts_baseline() decorator executed on %s', func.__name__)
|
||||
|
||||
return func
|
||||
return wrapper(args[0])
|
||||
|
@ -24,11 +24,13 @@ from bandit.core import blacklisting
|
||||
from bandit.core import extension_loader
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BanditTestSet():
|
||||
def __init__(self, config, profile={}):
|
||||
def __init__(self, config, profile=None):
|
||||
if not profile:
|
||||
profile = {}
|
||||
extman = extension_loader.MANAGER
|
||||
filtering = self._get_filter(config, profile)
|
||||
self.plugins = [p for p in extman.plugins
|
||||
@ -109,8 +111,8 @@ class BanditTestSet():
|
||||
plugin.plugin._config = cfg
|
||||
for check in plugin.plugin._checks:
|
||||
self.tests.setdefault(check, []).append(plugin.plugin)
|
||||
logger.debug('added function %s (%s) targetting %s',
|
||||
plugin.name, plugin.plugin._test_id, check)
|
||||
LOG.debug('added function %s (%s) targetting %s',
|
||||
plugin.name, plugin.plugin._test_id, check)
|
||||
|
||||
def get_tests(self, checktype):
|
||||
'''Returns all tests that are of type checktype
|
||||
|
@ -23,7 +23,7 @@ from bandit.core import context as b_context
|
||||
from bandit.core import utils
|
||||
|
||||
warnings.formatwarning = utils.warnings_formatter
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BanditTester():
|
||||
@ -77,9 +77,7 @@ class BanditTester():
|
||||
|
||||
self.results.append(result)
|
||||
|
||||
logger.debug(
|
||||
"Issue identified by %s: %s", name, result
|
||||
)
|
||||
LOG.debug("Issue identified by %s: %s", name, result)
|
||||
sev = constants.RANKING.index(result.severity)
|
||||
val = constants.RANKING_VALUES[result.severity]
|
||||
scores['SEVERITY'][sev] += val
|
||||
@ -91,7 +89,7 @@ class BanditTester():
|
||||
self.report_error(name, context, e)
|
||||
if self.debug:
|
||||
raise
|
||||
logger.debug("Returning scores: %s", scores)
|
||||
LOG.debug("Returning scores: %s", scores)
|
||||
return scores
|
||||
|
||||
def report_error(self, test, context, error):
|
||||
@ -104,4 +102,4 @@ class BanditTester():
|
||||
what += str(error)
|
||||
import traceback
|
||||
what += traceback.format_exc()
|
||||
logger.error(what)
|
||||
LOG.error(what)
|
||||
|
@ -25,7 +25,7 @@ try:
|
||||
except ImportError:
|
||||
import ConfigParser as configparser
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
"""Various helper functions."""
|
||||
@ -46,11 +46,11 @@ def _get_attr_qual_name(node, aliases):
|
||||
:param aliases: Import aliases dictionary
|
||||
:returns: Qualified name referred to by the attribute or name.
|
||||
'''
|
||||
if type(node) == _ast.Name:
|
||||
if isinstance(node, _ast.Name):
|
||||
if node.id in aliases:
|
||||
return aliases[node.id]
|
||||
return node.id
|
||||
elif type(node) == _ast.Attribute:
|
||||
elif isinstance(node, _ast.Attribute):
|
||||
name = '%s.%s' % (_get_attr_qual_name(node.value, aliases), node.attr)
|
||||
if name in aliases:
|
||||
return aliases[name]
|
||||
@ -60,11 +60,11 @@ def _get_attr_qual_name(node, aliases):
|
||||
|
||||
|
||||
def get_call_name(node, aliases):
|
||||
if type(node.func) == _ast.Name:
|
||||
if isinstance(node.func, _ast.Name):
|
||||
if deepgetattr(node, 'func.id') in aliases:
|
||||
return aliases[deepgetattr(node, 'func.id')]
|
||||
return(deepgetattr(node, 'func.id'))
|
||||
elif type(node.func) == _ast.Attribute:
|
||||
return deepgetattr(node, 'func.id')
|
||||
elif isinstance(node.func, _ast.Attribute):
|
||||
return _get_attr_qual_name(node.func, aliases)
|
||||
else:
|
||||
return ""
|
||||
@ -76,7 +76,7 @@ def get_func_name(node):
|
||||
|
||||
def get_qual_attr(node, aliases):
|
||||
prefix = ""
|
||||
if type(node) == _ast.Attribute:
|
||||
if isinstance(node, _ast.Attribute):
|
||||
try:
|
||||
val = deepgetattr(node, 'value.id')
|
||||
if val in aliases:
|
||||
@ -88,7 +88,7 @@ def get_qual_attr(node, aliases):
|
||||
# qualified name for an attr, just return its base name.
|
||||
pass
|
||||
|
||||
return("%s.%s" % (prefix, node.attr))
|
||||
return "%s.%s" % (prefix, node.attr)
|
||||
else:
|
||||
return "" # TODO(tkelsey): process other node types
|
||||
|
||||
@ -122,10 +122,7 @@ class ProfileNotFound(Exception):
|
||||
super(ProfileNotFound, self).__init__(message)
|
||||
|
||||
|
||||
def warnings_formatter(message,
|
||||
category=UserWarning,
|
||||
filename='',
|
||||
lineno=-1,
|
||||
def warnings_formatter(message, category=UserWarning, filename='', lineno=-1,
|
||||
line=''):
|
||||
'''Monkey patch for warnings.warn to suppress cruft output.'''
|
||||
return "{0}\n".format(message)
|
||||
@ -286,7 +283,7 @@ def get_called_name(node):
|
||||
'''
|
||||
func = node.func
|
||||
try:
|
||||
return (func.attr if isinstance(func, ast.Attribute) else func.id)
|
||||
return func.attr if isinstance(func, ast.Attribute) else func.id
|
||||
except AttributeError:
|
||||
return ""
|
||||
|
||||
@ -303,14 +300,14 @@ def get_path_for_function(f):
|
||||
elif hasattr(f, "im_func"):
|
||||
module_name = f.im_func.__module__
|
||||
else:
|
||||
logger.warning("Cannot resolve file where %s is defined", f)
|
||||
LOG.warning("Cannot resolve file where %s is defined", f)
|
||||
return None
|
||||
|
||||
module = sys.modules[module_name]
|
||||
if hasattr(module, "__file__"):
|
||||
return module.__file__
|
||||
else:
|
||||
logger.warning("Cannot resolve file path for module %s", module_name)
|
||||
LOG.warning("Cannot resolve file path for module %s", module_name)
|
||||
return None
|
||||
|
||||
|
||||
@ -321,8 +318,8 @@ def parse_ini_file(f_loc):
|
||||
return {k: v for k, v in config.items('bandit')}
|
||||
|
||||
except (configparser.Error, KeyError, TypeError):
|
||||
logger.warning("Unable to parse config file %s or missing [bandit] "
|
||||
"section", f_loc)
|
||||
LOG.warning("Unable to parse config file %s or missing [bandit] "
|
||||
"section", f_loc)
|
||||
|
||||
return None
|
||||
|
||||
|
@ -40,7 +40,7 @@ import csv
|
||||
import logging
|
||||
import sys
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def report(manager, fileobj, sev_level, conf_level, lines=-1):
|
||||
@ -73,4 +73,4 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
|
||||
writer.writerow(result.as_dict(with_code=False))
|
||||
|
||||
if fileobj.name != sys.stdout.name:
|
||||
logger.info("CSV output written to file: %s" % fileobj.name)
|
||||
LOG.info("CSV output written to file: %s", fileobj.name)
|
||||
|
@ -153,7 +153,7 @@ import sys
|
||||
from bandit.core import docs_utils
|
||||
from bandit.core import test_properties
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@test_properties.accepts_baseline
|
||||
@ -376,4 +376,4 @@ pre {
|
||||
fileobj.write(str(report_contents.encode('utf-8')))
|
||||
|
||||
if fileobj.name != sys.stdout.name:
|
||||
logger.info("HTML output written to file: %s" % fileobj.name)
|
||||
LOG.info("HTML output written to file: %s", fileobj.name)
|
||||
|
@ -104,7 +104,7 @@ import six
|
||||
from bandit.core import constants
|
||||
from bandit.core import test_properties
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@test_properties.accepts_baseline
|
||||
@ -182,4 +182,4 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
|
||||
fileobj.write(result)
|
||||
|
||||
if fileobj.name != sys.stdout.name:
|
||||
logger.info("JSON output written to file: %s" % fileobj.name)
|
||||
LOG.info("JSON output written to file: %s", fileobj.name)
|
||||
|
@ -46,9 +46,9 @@ import sys
|
||||
from bandit.core import constants
|
||||
from bandit.core import test_properties
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
color = {
|
||||
COLOR = {
|
||||
'DEFAULT': '\033[0m',
|
||||
'HEADER': '\033[95m',
|
||||
'LOW': '\033[94m',
|
||||
@ -58,7 +58,7 @@ color = {
|
||||
|
||||
|
||||
def header(text, *args):
|
||||
return u'%s%s%s' % (color['HEADER'], (text % args), color['DEFAULT'])
|
||||
return u'%s%s%s' % (COLOR['HEADER'], (text % args), COLOR['DEFAULT'])
|
||||
|
||||
|
||||
def get_verbose_details(manager):
|
||||
@ -90,7 +90,7 @@ def _output_issue_str(issue, indent, show_lineno=True, show_code=True,
|
||||
# returns a list of lines that should be added to the existing lines list
|
||||
bits = []
|
||||
bits.append("%s%s>> Issue: [%s:%s] %s" % (
|
||||
indent, color[issue.severity], issue.test_id, issue.test, issue.text))
|
||||
indent, COLOR[issue.severity], issue.test_id, issue.test, issue.text))
|
||||
|
||||
bits.append("%s Severity: %s Confidence: %s" % (
|
||||
indent, issue.severity.capitalize(), issue.confidence.capitalize()))
|
||||
@ -98,7 +98,7 @@ def _output_issue_str(issue, indent, show_lineno=True, show_code=True,
|
||||
bits.append("%s Location: %s:%s%s" % (
|
||||
indent, issue.fname,
|
||||
issue.lineno if show_lineno else "",
|
||||
color['DEFAULT']))
|
||||
COLOR['DEFAULT']))
|
||||
|
||||
if show_code:
|
||||
bits.extend([indent + l for l in
|
||||
@ -177,5 +177,5 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
|
||||
do_print(bits)
|
||||
|
||||
if fileobj.name != sys.stdout.name:
|
||||
logger.info(("Screen formatter output was not written to file: %s"
|
||||
", consider '-f txt'") % fileobj.name)
|
||||
LOG.info("Screen formatter output was not written to file: %s, "
|
||||
"consider '-f txt'", fileobj.name)
|
||||
|
@ -46,7 +46,7 @@ import sys
|
||||
from bandit.core import constants
|
||||
from bandit.core import test_properties
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_verbose_details(manager):
|
||||
@ -158,4 +158,4 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
|
||||
fileobj.write(str(result.encode('utf-8')))
|
||||
|
||||
if fileobj.name != sys.stdout.name:
|
||||
logger.info("Text output written to file: %s", fileobj.name)
|
||||
LOG.info("Text output written to file: %s", fileobj.name)
|
||||
|
@ -46,7 +46,7 @@ from xml.etree import cElementTree as ET
|
||||
|
||||
import six
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def report(manager, fileobj, sev_level, conf_level, lines=-1):
|
||||
@ -88,4 +88,4 @@ def report(manager, fileobj, sev_level, conf_level, lines=-1):
|
||||
tree.write(fileobj, encoding='utf-8', xml_declaration=True)
|
||||
|
||||
if fileobj.name != sys.stdout.name:
|
||||
logger.info("XML output written to file: %s" % fileobj.name)
|
||||
LOG.info("XML output written to file: %s", fileobj.name)
|
||||
|
@ -57,9 +57,9 @@ from bandit.core import test_properties as test
|
||||
@test.test_id('B101')
|
||||
@test.checks('Assert')
|
||||
def assert_used(context):
|
||||
return bandit.Issue(
|
||||
severity=bandit.LOW,
|
||||
confidence=bandit.HIGH,
|
||||
text=("Use of assert detected. The enclosed code "
|
||||
"will be removed when compiling to optimised byte code.")
|
||||
)
|
||||
return bandit.Issue(
|
||||
severity=bandit.LOW,
|
||||
confidence=bandit.HIGH,
|
||||
text=("Use of assert detected. The enclosed code "
|
||||
"will be removed when compiling to optimised byte code.")
|
||||
)
|
||||
|
@ -70,10 +70,8 @@ def set_bad_file_permissions(context):
|
||||
if context.call_args_count == 2:
|
||||
mode = context.get_call_arg_at_position(1)
|
||||
|
||||
if (
|
||||
mode is not None and type(mode) == int and
|
||||
(mode & stat.S_IWOTH or mode & stat.S_IXGRP)
|
||||
):
|
||||
if (mode is not None and isinstance(mode, int) and
|
||||
(mode & stat.S_IWOTH or mode & stat.S_IXGRP)):
|
||||
# world writable is an HIGH, group executable is a MEDIUM
|
||||
if mode & stat.S_IWOTH:
|
||||
sev_level = bandit.HIGH
|
||||
@ -87,5 +85,5 @@ def set_bad_file_permissions(context):
|
||||
severity=sev_level,
|
||||
confidence=bandit.HIGH,
|
||||
text="Chmod setting a permissive mask %s on file (%s)." %
|
||||
(oct(mode), filename)
|
||||
(oct(mode), filename)
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ import bandit
|
||||
from bandit.core import test_properties as test
|
||||
|
||||
|
||||
candidates = set(["password", "pass", "passwd", "pwd", "secret", "token",
|
||||
CANDIDATES = set(["password", "pass", "passwd", "pwd", "secret", "token",
|
||||
"secrete"])
|
||||
|
||||
|
||||
@ -84,10 +84,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 targ.id in CANDIDATES:
|
||||
return _report(node.s)
|
||||
|
||||
elif isinstance(node.parent, ast.Index) and node.s in candidates:
|
||||
elif isinstance(node.parent, ast.Index) and node.s in CANDIDATES:
|
||||
# looks for "dict[candidate]='some_string'"
|
||||
# assign -> subscript -> index -> string
|
||||
assign = node.parent.parent.parent
|
||||
@ -98,7 +98,7 @@ 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.left, ast.Name) and comp.left.id in CANDIDATES:
|
||||
if isinstance(comp.comparators[0], ast.Str):
|
||||
return _report(comp.comparators[0].s)
|
||||
|
||||
@ -150,7 +150,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 kw.arg in CANDIDATES:
|
||||
return _report(kw.value.s)
|
||||
|
||||
|
||||
@ -211,5 +211,5 @@ def hardcoded_password_default(context):
|
||||
for key, val in zip(context.node.args.args, defs):
|
||||
if isinstance(key, ast.Name):
|
||||
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 check in CANDIDATES:
|
||||
return _report(val.s)
|
||||
|
@ -73,7 +73,7 @@ def gen_config(name):
|
||||
@test.checks('Str')
|
||||
@test.test_id('B108')
|
||||
def hardcoded_tmp_directory(context, config):
|
||||
if (config is not None and 'tmp_dirs' in config):
|
||||
if config is not None and 'tmp_dirs' in config:
|
||||
tmp_dirs = config['tmp_dirs']
|
||||
else:
|
||||
tmp_dirs = ['/tmp', '/var/tmp', '/dev/shm']
|
||||
|
@ -656,7 +656,7 @@ def start_process_with_partial_path(context, config):
|
||||
node = node.elts[0]
|
||||
|
||||
# make sure the param is a string literal and not a var name
|
||||
if(isinstance(node, ast.Str) and node.s[0] not in delims):
|
||||
if isinstance(node, ast.Str) and node.s[0] not in delims:
|
||||
return bandit.Issue(
|
||||
severity=bandit.LOW,
|
||||
confidence=bandit.HIGH,
|
||||
|
@ -144,6 +144,6 @@ def linux_commands_wildcard_injection(context, config):
|
||||
severity=bandit.HIGH,
|
||||
confidence=bandit.MEDIUM,
|
||||
text="Possible wildcard injection in call: %s" %
|
||||
context.call_function_name_qual,
|
||||
context.call_function_name_qual,
|
||||
lineno=context.get_lineno_for_call_arg('shell'),
|
||||
)
|
||||
|
@ -31,8 +31,7 @@ def gen_config(name):
|
||||
'PROTOCOL_SSLv3', # strict option
|
||||
'PROTOCOL_TLSv1', # strict option
|
||||
'SSLv3_METHOD', # strict option
|
||||
'TLSv1_METHOD'] # strict option
|
||||
}
|
||||
'TLSv1_METHOD']} # strict option
|
||||
|
||||
|
||||
@test.takes_config
|
||||
@ -117,7 +116,7 @@ def ssl_with_bad_version(context, config):
|
||||
.. versionadded:: 0.9.0
|
||||
"""
|
||||
bad_ssl_versions = get_bad_proto_versions(config)
|
||||
if (context.call_function_name_qual == 'ssl.wrap_socket'):
|
||||
if context.call_function_name_qual == 'ssl.wrap_socket':
|
||||
if context.check_call_arg_value('ssl_version', bad_ssl_versions):
|
||||
return bandit.Issue(
|
||||
severity=bandit.HIGH,
|
||||
@ -126,7 +125,7 @@ def ssl_with_bad_version(context, config):
|
||||
"version identified, security issue.",
|
||||
lineno=context.get_lineno_for_call_arg('ssl_version'),
|
||||
)
|
||||
elif (context.call_function_name_qual == 'pyOpenSSL.SSL.Context'):
|
||||
elif context.call_function_name_qual == 'pyOpenSSL.SSL.Context':
|
||||
if context.check_call_arg_value('method', bad_ssl_versions):
|
||||
return bandit.Issue(
|
||||
severity=bandit.HIGH,
|
||||
@ -139,7 +138,7 @@ def ssl_with_bad_version(context, config):
|
||||
elif (context.call_function_name_qual != 'ssl.wrap_socket' and
|
||||
context.call_function_name_qual != 'pyOpenSSL.SSL.Context'):
|
||||
if (context.check_call_arg_value('method', bad_ssl_versions) or
|
||||
context.check_call_arg_value('ssl_version', bad_ssl_versions)):
|
||||
context.check_call_arg_value('ssl_version', bad_ssl_versions)):
|
||||
lineno = (context.get_lineno_for_call_arg('method') or
|
||||
context.get_lineno_for_call_arg('ssl_version'))
|
||||
return bandit.Issue(
|
||||
@ -259,7 +258,7 @@ def ssl_with_no_version(context):
|
||||
|
||||
.. versionadded:: 0.9.0
|
||||
"""
|
||||
if (context.call_function_name_qual == 'ssl.wrap_socket'):
|
||||
if context.call_function_name_qual == 'ssl.wrap_socket':
|
||||
if context.check_call_arg_value('ssl_version') is None:
|
||||
# check_call_arg_value() returns False if the argument is found
|
||||
# but does not match the supplied value (or the default None).
|
||||
|
@ -78,7 +78,7 @@ from bandit.core import test_properties as test
|
||||
@test.test_id('B701')
|
||||
def jinja2_autoescape_false(context):
|
||||
# check type just to be safe
|
||||
if type(context.call_function_name_qual) == str:
|
||||
if isinstance(context.call_function_name_qual, str):
|
||||
qualname_list = context.call_function_name_qual.split('.')
|
||||
func = qualname_list[-1]
|
||||
if 'jinja2' in qualname_list and func == 'Environment':
|
||||
@ -87,7 +87,7 @@ def jinja2_autoescape_false(context):
|
||||
# definite autoescape = False
|
||||
if (getattr(node, 'arg', None) == 'autoescape' and
|
||||
(getattr(node.value, 'id', None) == 'False' or
|
||||
getattr(node.value, 'value', None) is False)):
|
||||
getattr(node.value, 'value', None) is False)):
|
||||
return bandit.Issue(
|
||||
severity=bandit.HIGH,
|
||||
confidence=bandit.HIGH,
|
||||
|
@ -59,7 +59,7 @@ from bandit.core import test_properties as test
|
||||
@test.test_id('B702')
|
||||
def use_of_mako_templates(context):
|
||||
# check type just to be safe
|
||||
if type(context.call_function_name_qual) == str:
|
||||
if isinstance(context.call_function_name_qual, str):
|
||||
qualname_list = context.call_function_name_qual.split('.')
|
||||
func = qualname_list[-1]
|
||||
if 'mako' in qualname_list and func == 'Template':
|
||||
|
@ -99,9 +99,9 @@ def try_except_continue(context, config):
|
||||
node = context.node
|
||||
if len(node.body) == 1:
|
||||
if (not config['check_typed_exception'] and
|
||||
node.type is not None and
|
||||
getattr(node.type, 'id', None) != 'Exception'):
|
||||
return
|
||||
node.type is not None and
|
||||
getattr(node.type, 'id', None) != 'Exception'):
|
||||
return
|
||||
|
||||
if isinstance(node.body[0], ast.Continue):
|
||||
return bandit.Issue(
|
||||
|
@ -98,9 +98,9 @@ def try_except_pass(context, config):
|
||||
node = context.node
|
||||
if len(node.body) == 1:
|
||||
if (not config['check_typed_exception'] and
|
||||
node.type is not None and
|
||||
getattr(node.type, 'id', None) != 'Exception'):
|
||||
return
|
||||
node.type is not None and
|
||||
getattr(node.type, 'id', None) != 'Exception'):
|
||||
return
|
||||
|
||||
if isinstance(node.body[0], ast.Pass):
|
||||
return bandit.Issue(
|
||||
|
@ -67,7 +67,7 @@ def _classify_key_size(key_type, key_size):
|
||||
severity=level,
|
||||
confidence=bandit.HIGH,
|
||||
text='%s key sizes below %d bits are considered breakable. ' %
|
||||
(key_type, size))
|
||||
(key_type, size))
|
||||
|
||||
|
||||
def _weak_crypto_key_size_cryptography_io(context):
|
||||
|
@ -55,7 +55,7 @@ from bandit.core import test_properties as test
|
||||
@test.test_id('B506')
|
||||
@test.checks('Call')
|
||||
def yaml_load(context):
|
||||
if type(context.call_function_name_qual) == str:
|
||||
if isinstance(context.call_function_name_qual, str):
|
||||
qualname_list = context.call_function_name_qual.split('.')
|
||||
func = qualname_list[-1]
|
||||
if 'yaml' in qualname_list and func == 'load':
|
||||
|
76
pylintrc
Normal file
76
pylintrc
Normal file
@ -0,0 +1,76 @@
|
||||
# The format of this file isn't really documented; just use --generate-rcfile
|
||||
|
||||
[Messages Control]
|
||||
# C0111: Don't require docstrings on every method
|
||||
# C0301: Handled by pep8
|
||||
# C0325: Parens are required on print in py3x
|
||||
# F0401: Imports are check by other linters
|
||||
# W0511: TODOs in code comments are fine.
|
||||
# W0142: *args and **kwargs are fine.
|
||||
# W0622: Redefining id is fine.
|
||||
|
||||
# TODO(browne): fix these in the future
|
||||
# C0103: invalid-name
|
||||
# C1001: old-style-class
|
||||
# E1101: no-member
|
||||
# R0201: no-self-use
|
||||
# R0204: redefined-variable-typ
|
||||
# R0902: too-many-instance-attributes
|
||||
# R0911: too-many-return-statements
|
||||
# R0912: too-many-branches
|
||||
# R0913: too-many-arguments
|
||||
# R0914: too-many-locals
|
||||
# R0915: too-many-statements
|
||||
# W0110: deprecated-lambda
|
||||
# W0141: bad-builtin
|
||||
# W0201: attribute-defined-outside-init
|
||||
# W0212: protected-access
|
||||
# W0401: wildcard-import
|
||||
# W0603: global-statement
|
||||
# W0612: unused-variable
|
||||
# W0613: unused-argument
|
||||
# W0621: redefined-outer-name
|
||||
# W0703: broad-except
|
||||
disable=C0111,C0301,C0325,C1001,F0401,W0511,W0142,W0622,C0103,E1101,R0201,R0204,R0902,R0911,R0912,R0913,R0914,R0915,W0110,W0141,W0201,W0401,W0603,W0212,W0612,W0613,W0621,W0703
|
||||
|
||||
[Basic]
|
||||
# Variable names can be 1 to 31 characters long, with lowercase and underscores
|
||||
variable-rgx=[a-z_][a-z0-9_]{0,30}$
|
||||
|
||||
# Argument names can be 2 to 31 characters long, with lowercase and underscores
|
||||
argument-rgx=[a-z_][a-z0-9_]{1,30}$
|
||||
|
||||
# Method names should be at least 3 characters long
|
||||
# and be lowecased with underscores
|
||||
method-rgx=([a-z_][a-z0-9_]{2,50}|setUp|tearDown)$
|
||||
|
||||
# Module names matching manila-* are ok (files in bin/)
|
||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+)|(manila-[a-z0-9_-]+))$
|
||||
|
||||
# Don't require docstrings on tests.
|
||||
no-docstring-rgx=((__.*__)|([tT]est.*)|setUp|tearDown)$
|
||||
|
||||
[Design]
|
||||
max-public-methods=100
|
||||
min-public-methods=0
|
||||
max-args=6
|
||||
|
||||
[Variables]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
# _ is used by our localization
|
||||
additional-builtins=_
|
||||
|
||||
[Similarities]
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=10
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=yes
|
@ -15,3 +15,5 @@ sphinx!=1.3b1,<1.4,>=1.2.1 # BSD
|
||||
oslosphinx>=4.7.0 # Apache-2.0
|
||||
beautifulsoup4 # MIT
|
||||
reno>=1.8.0 # Apache-2.0
|
||||
|
||||
pylint==1.4.5 # GPLv2
|
||||
|
@ -189,7 +189,7 @@ class BanditBaselineToolTests(testtools.TestCase):
|
||||
def test_init_logger(self):
|
||||
# Test whether the logger was initialized when calling init_logger
|
||||
baseline.init_logger()
|
||||
logger = baseline.logger
|
||||
logger = baseline.LOG
|
||||
|
||||
# verify that logger was initialized
|
||||
self.assertIsNotNone(logger)
|
||||
|
@ -187,7 +187,7 @@ class BanditCLIMainTests(testtools.TestCase):
|
||||
"skips": "skip_test",
|
||||
"tests": "some_test"}
|
||||
|
||||
with mock.patch('bandit.cli.main.logger.error') as err_mock:
|
||||
with mock.patch('bandit.cli.main.LOG.error') as err_mock:
|
||||
# SystemExit with code 2 when test not found in profile
|
||||
self.assertRaisesRegex(SystemExit, '2', bandit.main)
|
||||
self.assertEqual(str(err_mock.call_args[0][0]),
|
||||
@ -224,7 +224,7 @@ class BanditCLIMainTests(testtools.TestCase):
|
||||
with open('bandit.yaml', 'wt') as fd:
|
||||
fd.write(bandit_config_content)
|
||||
# assert a SystemExit with code 2
|
||||
with mock.patch('bandit.cli.main.logger.error') as err_mock:
|
||||
with mock.patch('bandit.cli.main.LOG.error') as err_mock:
|
||||
self.assertRaisesRegex(SystemExit, '2', bandit.main)
|
||||
self.assertEqual(
|
||||
str(err_mock.call_args[0][0]),
|
||||
|
@ -233,7 +233,7 @@ class TestConfigCompat(testtools.TestCase):
|
||||
"'bandit-config-generator' can help you with this. Support for "
|
||||
"legacy configs will be removed in a future bandit version.")
|
||||
|
||||
with mock.patch('bandit.core.config.logger.warn') as m:
|
||||
with mock.patch('bandit.core.config.LOG.warn') as m:
|
||||
self.config._config = {"profiles": {}}
|
||||
self.config.validate('')
|
||||
self.assertEqual((msg, ''), m.call_args_list[0][0])
|
||||
|
@ -46,27 +46,27 @@ class ScreenFormatterTests(testtools.TestCase):
|
||||
_issue.confidence.capitalize()),
|
||||
"{} Location: {}:{}{}".
|
||||
format(_indent_val, _issue.fname, _issue.lineno,
|
||||
screen.color['DEFAULT'])]
|
||||
screen.COLOR['DEFAULT'])]
|
||||
if _code:
|
||||
return_val.append("{}{}".format(_indent_val, _code))
|
||||
return '\n'.join(return_val)
|
||||
|
||||
issue_text = screen._output_issue_str(issue, indent_val)
|
||||
expected_return = _template(issue, indent_val, 'DDDDDDD',
|
||||
screen.color['MEDIUM'])
|
||||
screen.COLOR['MEDIUM'])
|
||||
self.assertEqual(expected_return, issue_text)
|
||||
|
||||
issue_text = screen._output_issue_str(issue, indent_val,
|
||||
show_code=False)
|
||||
expected_return = _template(issue, indent_val, '',
|
||||
screen.color['MEDIUM'])
|
||||
screen.COLOR['MEDIUM'])
|
||||
self.assertEqual(expected_return, issue_text)
|
||||
|
||||
issue.lineno = ''
|
||||
issue_text = screen._output_issue_str(issue, indent_val,
|
||||
show_lineno=False)
|
||||
expected_return = _template(issue, indent_val, 'DDDDDDD',
|
||||
screen.color['MEDIUM'])
|
||||
screen.COLOR['MEDIUM'])
|
||||
self.assertEqual(expected_return, issue_text)
|
||||
|
||||
@mock.patch('bandit.core.manager.BanditManager.get_issue_list')
|
||||
|
4
tox.ini
4
tox.ini
@ -32,6 +32,7 @@ deps = {[testenv]deps}
|
||||
.
|
||||
commands = flake8 {posargs} bandit
|
||||
flake8 {posargs} tests
|
||||
{[testenv:pylint]commands}
|
||||
bandit-baseline -r bandit -ll -ii
|
||||
|
||||
[testenv:venv]
|
||||
@ -68,3 +69,6 @@ exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,rele
|
||||
|
||||
[testenv:releasenotes]
|
||||
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
|
||||
|
||||
[testenv:pylint]
|
||||
commands = pylint --rcfile=pylintrc bandit
|
||||
|
Loading…
x
Reference in New Issue
Block a user