Merge "Blacklists now check node types are valid"

This commit is contained in:
Jenkins 2016-03-23 18:21:59 +00:00 committed by Gerrit Code Review
commit c562ebb9bb
6 changed files with 41 additions and 29 deletions

View File

@ -19,6 +19,8 @@ import sys
import six
from stevedore import extension
from bandit.core import utils
class Manager(object):
# These IDs are for bandit built in tests
@ -77,7 +79,8 @@ class Manager(object):
self.blacklist = {}
blacklist = list(self.blacklists_mgr)
for item in blacklist:
for key, val in six.iteritems(item.plugin()):
for key, val in item.plugin().items():
utils.check_ast_node(key)
self.blacklist.setdefault(key, []).extend(val)
self.blacklist_by_id = {}
@ -91,15 +94,15 @@ class Manager(object):
'''Validate that everything in the configured profiles looks good.'''
for inc in profile['include']:
if not self.check_id(inc):
raise ValueError('Unknown Test found in profile: %s' % inc)
raise ValueError('Unknown test found in profile: %s' % inc)
for exc in profile['exclude']:
if not self.check_id(exc):
raise ValueError('Unknown Test found in profile: %s' % exc)
raise ValueError('Unknown test found in profile: %s' % exc)
union = set(profile['include']) & set(profile['exclude'])
if len(union) > 0:
raise ValueError('None exclusive include/excule test sets: %s' %
raise ValueError('Non-exclusive include/exclude test sets: %s' %
union)
def check_id(self, test):

View File

@ -13,9 +13,10 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import ast
import logging
from bandit.core import utils
logger = logging.getLogger(__name__)
@ -25,20 +26,8 @@ def checks(*args):
def wrapper(func):
if not hasattr(func, "_checks"):
func._checks = []
for a in args:
try:
holder = getattr(ast, a)
except AttributeError:
raise TypeError(
"Error: %s is not a valid node type in AST" % a
)
else:
if holder and issubclass(holder, ast.AST):
func._checks.append(a)
else:
raise TypeError(
"Error: %s is not a valid node type in AST" % a
)
func._checks.extend(utils.check_ast_node(a) for a in args)
logger.debug('checks() decorator executed')
logger.debug(' func._checks: %s', func._checks)
return func

View File

@ -342,3 +342,15 @@ def parse_ini_file(f_loc):
"section", f_loc)
return None
def check_ast_node(name):
'Check if the given name is that of a valid AST node.'
try:
node = getattr(ast, name)
if issubclass(node, ast.AST):
return name
except AttributeError: # nosec(tkelsey): catching expected exception
pass
raise TypeError("Error: %s is not a valid node type in AST" % name)

View File

@ -190,7 +190,7 @@ class BanditCLIMainTests(testtools.TestCase):
# 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]),
'Unknown Test found in profile: some_test')
'Unknown test found in profile: some_test')
@patch('sys.argv', ['bandit', '-c', 'bandit.yaml', '-t', 'badID', 'test'])
def test_main_unknown_tests(self):

View File

@ -40,9 +40,7 @@ def test_plugin():
'Deserialization with the marshal module is possibly dangerous.'
))
return {'Import': sets,
'ImportFrom': sets,
'Calls': sets}
return {'Import': sets, 'ImportFrom': sets, 'Call': sets}
class BanditTestSetTests(testtools.TestCase):
@ -94,14 +92,14 @@ class BanditTestSetTests(testtools.TestCase):
ts = test_set.BanditTestSet(self.config)
self.assertEqual(len(ts.get_tests('Import')), 1)
self.assertEqual(len(ts.get_tests('ImportFrom')), 1)
self.assertEqual(len(ts.get_tests('Calls')), 1)
self.assertEqual(len(ts.get_tests('Call')), 1)
def test_profile_exclude_builtin_blacklist(self):
profile = {'exclude': ['B001']}
ts = test_set.BanditTestSet(self.config, profile)
self.assertEqual(len(ts.get_tests('Import')), 0)
self.assertEqual(len(ts.get_tests('ImportFrom')), 0)
self.assertEqual(len(ts.get_tests('Calls')), 0)
self.assertEqual(len(ts.get_tests('Call')), 0)
def test_profile_filter_blacklist_none(self):
ts = test_set.BanditTestSet(self.config)
@ -109,7 +107,7 @@ class BanditTestSetTests(testtools.TestCase):
self.assertEqual(len(blacklist._config['Import']), 2)
self.assertEqual(len(blacklist._config['ImportFrom']), 2)
self.assertEqual(len(blacklist._config['Calls']), 2)
self.assertEqual(len(blacklist._config['Call']), 2)
def test_profile_filter_blacklist_one(self):
profile = {'exclude': ['B401']}
@ -118,7 +116,7 @@ class BanditTestSetTests(testtools.TestCase):
self.assertEqual(len(blacklist._config['Import']), 1)
self.assertEqual(len(blacklist._config['ImportFrom']), 1)
self.assertEqual(len(blacklist._config['Calls']), 1)
self.assertEqual(len(blacklist._config['Call']), 1)
def test_profile_filter_blacklist_include(self):
profile = {'include': ['B001', 'B401']}
@ -127,7 +125,7 @@ class BanditTestSetTests(testtools.TestCase):
self.assertEqual(len(blacklist._config['Import']), 1)
self.assertEqual(len(blacklist._config['ImportFrom']), 1)
self.assertEqual(len(blacklist._config['Calls']), 1)
self.assertEqual(len(blacklist._config['Call']), 1)
def test_profile_filter_blacklist_all(self):
profile = {'exclude': ['B401', 'B302']}
@ -137,7 +135,7 @@ class BanditTestSetTests(testtools.TestCase):
# blacklist test to it, as this would be pointless.
self.assertEqual(len(ts.get_tests('Import')), 0)
self.assertEqual(len(ts.get_tests('ImportFrom')), 0)
self.assertEqual(len(ts.get_tests('Calls')), 0)
self.assertEqual(len(ts.get_tests('Call')), 0)
def test_profile_blacklist_compat(self):
data = [utils.build_conf_dict(

View File

@ -317,3 +317,13 @@ class UtilTests(testtools.TestCase):
pass
self.assertRaises(IOError, _b_tester, 'derp', 'r')
def test_check_ast_node_good(self):
node = b_utils.check_ast_node("Call")
self.assertEqual("Call", node)
def test_check_ast_node_bad_node(self):
self.assertRaises(TypeError, b_utils.check_ast_node, 'Derp')
def test_check_ast_node_bad_type(self):
self.assertRaises(TypeError, b_utils.check_ast_node, 'walk')