1# -*- coding:utf-8 -*- 2# 3# Copyright 2014 Hewlett-Packard Development Company, L.P. 4# 5# SPDX-License-Identifier: Apache-2.0 6 7import copy 8import logging 9import warnings 10 11from bandit.core import constants 12from bandit.core import context as b_context 13from bandit.core import utils 14 15warnings.formatwarning = utils.warnings_formatter 16LOG = logging.getLogger(__name__) 17 18 19class BanditTester(object): 20 def __init__(self, testset, debug, nosec_lines): 21 self.results = [] 22 self.testset = testset 23 self.last_result = None 24 self.debug = debug 25 self.nosec_lines = nosec_lines 26 27 def run_tests(self, raw_context, checktype): 28 '''Runs all tests for a certain type of check, for example 29 30 Runs all tests for a certain type of check, for example 'functions' 31 store results in results. 32 33 :param raw_context: Raw context dictionary 34 :param checktype: The type of checks to run 35 :param nosec_lines: Lines which should be skipped because of nosec 36 :return: a score based on the number and type of test results 37 ''' 38 39 scores = { 40 'SEVERITY': [0] * len(constants.RANKING), 41 'CONFIDENCE': [0] * len(constants.RANKING) 42 } 43 44 tests = self.testset.get_tests(checktype) 45 for test in tests: 46 name = test.__name__ 47 # execute test with the an instance of the context class 48 temp_context = copy.copy(raw_context) 49 context = b_context.Context(temp_context) 50 try: 51 if hasattr(test, '_config'): 52 result = test(context, test._config) 53 else: 54 result = test(context) 55 56 # if we have a result, record it and update scores 57 if (result is not None and 58 result.lineno not in self.nosec_lines and 59 temp_context['lineno'] not in self.nosec_lines): 60 61 if isinstance(temp_context['filename'], bytes): 62 result.fname = temp_context['filename'].decode('utf-8') 63 else: 64 result.fname = temp_context['filename'] 65 66 if result.lineno is None: 67 result.lineno = temp_context['lineno'] 68 result.linerange = temp_context['linerange'] 69 result.col_offset = temp_context['col_offset'] 70 result.test = name 71 if result.test_id == "": 72 result.test_id = test._test_id 73 74 self.results.append(result) 75 76 LOG.debug("Issue identified by %s: %s", name, result) 77 sev = constants.RANKING.index(result.severity) 78 val = constants.RANKING_VALUES[result.severity] 79 scores['SEVERITY'][sev] += val 80 con = constants.RANKING.index(result.confidence) 81 val = constants.RANKING_VALUES[result.confidence] 82 scores['CONFIDENCE'][con] += val 83 84 except Exception as e: 85 self.report_error(name, context, e) 86 if self.debug: 87 raise 88 LOG.debug("Returning scores: %s", scores) 89 return scores 90 91 @staticmethod 92 def report_error(test, context, error): 93 what = "Bandit internal error running: " 94 what += "%s " % test 95 what += "on file %s at line %i: " % ( 96 context._context['filename'], 97 context._context['lineno'] 98 ) 99 what += str(error) 100 import traceback 101 what += traceback.format_exc() 102 LOG.error(what) 103