Register plugins included as entry-points

Previously, we tried to load the default plugins by using the path to
bandit to import them dynamically and load them. This is unreliable on
systems where the default path and the actual path are different
depending on how bandit is installed. By using entry-points, we can
completely side-step this problem.

 _______
< FIXED >
 -------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Closes-Bug: #1475681
Co-Authored-By: Ian Cordasco <graffatcolmingov@gmail.com>
Signed-off-by: Dave Walker (Daviey) <email@daviey.com>
Change-Id: I19eed3b312c921e98bdabfb346cddd406186d963
This commit is contained in:
Dave Walker (Daviey) 2015-07-17 16:39:46 +01:00 committed by Ian Cordasco
parent 01439f0964
commit 20c12cde76
4 changed files with 109 additions and 104 deletions

View File

@ -103,7 +103,6 @@ class BanditConfig():
'''
self._init_progress_increment()
self._init_output_colors()
self._init_plugins_dir()
self._init_plugin_name_pattern()
def _init_progress_increment(self):
@ -148,13 +147,6 @@ class BanditConfig():
settings_string = 'color_' + color
self._settings[settings_string] = color_settings[color]
def _init_plugins_dir(self):
'''Sets settings['plugins_dir'] from default or config file.'''
plugins_dir = constants.plugins_dir
if self.get_option('plugins_dir'):
plugins_dir = self.get_option('plugins_dir')
self._settings['plugins_dir'] = plugins_dir
def _init_plugin_name_pattern(self):
'''Sets settings['plugin_name_pattern'] from default or config file.'''
plugin_name_pattern = constants.plugin_name_pattern

View File

@ -14,10 +14,6 @@
# License for the specific language governing permissions and limitations
# under the License.
from distutils.sysconfig import get_python_lib
import os
# default output text colors
color = {
'DEFAULT': '\033[0m',
@ -33,9 +29,6 @@ plugin_name_pattern = '*.py'
# default progress increment
progress_increment = 50
# default plugins dir
plugins_dir = os.path.join(get_python_lib(), 'bandit', 'plugins')
# flag/s used to mark lines where identified issues should not be reported
SKIP_FLAGS = ['nosec', ]

View File

@ -17,11 +17,6 @@
from collections import OrderedDict
import copy
import glob
import importlib
from inspect import getmembers
from inspect import isfunction
import os
import sys
@ -107,97 +102,38 @@ class BanditTestSet():
for k in self.tests:
self.logger.debug('\t%s : %s', k, self.tests[k])
def _get_decorators_list(self):
'''Returns a list of decorator function names
Returns a list of decorator function names so that they can be
ignored when discovering test function names.
'''
# we need to know the name of the decorators so we can automatically
# ignore them when discovering functions
decorator_source_file = "bandit.core.test_properties"
module = importlib.import_module(decorator_source_file)
return_list = []
decorators = [o for o in getmembers(module) if isfunction(o[1])]
for d in decorators:
return_list.append(d[0])
self.logger.debug('_get_decorators_list returning: %s', return_list)
return return_list
def _get_extension_manager(self):
from bandit.core import extension_loader
return extension_loader.MANAGER
def load_tests(self, filter=None):
'''Loads all tests in the plugins directory into testsdictionary.'''
# tests are a dictionary of functions, grouped by check type
# where the key is the function name, and the value is the
# function itself.
# eg. tests[check_type][fn_name] = function
self.tests = dict()
directory = self.config.get_setting('plugins_dir')
plugin_name_pattern = self.config.get_setting('plugin_name_pattern')
extmgr = self._get_extension_manager()
decorators = self._get_decorators_list()
# try to import each python file in the plugins directory
sys.path.append(os.path.dirname(directory))
for file in glob.glob1(directory, plugin_name_pattern):
module_name = os.path.basename(file).split('.')[0]
# try to import the module by name
try:
outer = os.path.basename(os.path.normpath(directory))
self.logger.debug("importing plugin module: %s",
outer + '.' + module_name)
module = importlib.import_module(outer + '.' + module_name)
# if it fails, die
except ImportError as e:
self.logger.error("could not import plugin module '%s.%s'",
directory, module_name)
self.logger.error("\tdetail: '%s'", str(e))
sys.exit(2)
# otherwise we want to obtain a list of all functions in the module
# and add them to our dictionary of tests
else:
functions_list = [
o for o in getmembers(module) if isfunction(o[1])
]
for cur_func in functions_list:
# for every function in the module, add to the dictionary
# unless it's one of our decorators, then ignore it
fn_name = cur_func[0]
if fn_name not in decorators:
try:
function = getattr(module, fn_name)
except AttributeError as e:
self.logger.error(
"could not locate test function '%s' in "
"module '%s.%s'",
fn_name, directory, module_name
for plugin in extmgr.plugins:
fn_name = plugin.name
function = plugin.plugin
if hasattr(function, '_checks'):
for check in function._checks:
# if check type hasn't been encountered
# yet, initialize to empty dictionary
if check not in self.tests:
self.tests[check] = {}
# if there is a test name collision, bail
if fn_name in self.tests[check]:
self.logger.error(
"Duplicate function definition "
"%s in %s", fn_name, file
)
sys.exit(2)
else:
self.tests[check][fn_name] = function
self.logger.debug(
'added function %s targetting %s',
fn_name, check
)
sys.exit(2)
else:
if hasattr(function, '_checks'):
for check in function._checks:
# if check type hasn't been encountered
# yet, initialize to empty dictionary
if check not in self.tests:
self.tests[check] = {}
# if there is a test name collision, bail
if fn_name in self.tests[check]:
self.logger.error(
"Duplicate function definition "
"%s in %s", fn_name, file
)
sys.exit(2)
else:
self.tests[check][fn_name] = function
self.logger.debug(
'added function %s targetting %s',
fn_name, check
)
self._filter_tests(filter)
def get_tests(self, checktype):

View File

@ -28,6 +28,90 @@ bandit.formatters =
json = bandit.core.formatters:report_json
txt = bandit.core.formatters:report_text
xml = bandit.core.formatters:report_xml
bandit.plugins =
# bandit/plugins/asserts.py
assert_used = bandit.plugins.asserts:assert_used
# bandit/plugins/blacklist_calls.py
blacklist_calls = bandit.plugins.blacklist_calls:blacklist_calls
# bandit/plugins/blacklist_imports.py
blacklist_imports = bandit.plugins.blacklist_imports:blacklist_imports
blacklist_import_func = bandit.plugins.blacklist_imports:blacklist_import_func
# bandit/plugins/crypto_request_no_cert_validation.py
request_with_no_cert_validation = bandit.plugins.crypto_request_no_cert_validation:request_with_no_cert_validation
# bandit/plugins/exec_as_root.py
execute_with_run_as_root_equals_true = bandit.plugins.exec_as_root:execute_with_run_as_root_equals_true
# bandit/plugins/exec.py
exec_used = bandit.plugins.exec:exec_used
# bandit/plugins/general_bad_File_permissions.py
set_bad_file_permissions = bandit.plugins.general_bad_file_permissions:set_bad_file_permissions
# bandit/plugins/general_bind_all_interfaces.py
hardcoded_bind_all_interfaces = bandit.plugins.general_bind_all_interfaces:hardcoded_bind_all_interfaces
# bandit/plugins/general_hardcoded_password.py
hardcoded_password = bandit.plugins.general_hardcoded_password:hardcoded_password
# bandit/plugins/general_hardcoded_tmp.py
hardcoded_tmp_directory = bandit.plugins.general_hardcoded_tmp:hardcoded_tmp_directory
# bandit/plugins/injection_paramiko.py
paramiko_calls = bandit.plugins.injection_paramiko:paramiko_calls
# bandit/plugins/injection_shell.py
subprocess_popen_with_shell_equals_true = bandit.plugins.injection_shell:subprocess_popen_with_shell_equals_true
subprocess_without_shell_equals_true = bandit.plugins.injection_shell:subprocess_without_shell_equals_true
any_other_function_with_shell_equals_true = bandit.plugins.injection_shell:any_other_function_with_shell_equals_true
start_process_with_a_shell = bandit.plugins.injection_shell:start_process_with_a_shell
start_process_with_no_shell = bandit.plugins.injection_shell:start_process_with_no_shell
start_process_with_partial_path = bandit.plugins.injection_shell:start_process_with_partial_path
# bandit/plugins/injection_sql.py
hardcoded_sql_expressions = bandit.plugins.injection_sql:hardcoded_sql_expressions
# bandit/plugins/injection_wildcard.py
linux_commands_wildcard_injection = bandit.plugins.injection_wildcard:linux_commands_wildcard_injection
# bandit/plugins/insecure_ssl_tls.py
ssl_with_bad_version = bandit.plugins.insecure_ssl_tls:ssl_with_bad_version
ssl_with_bad_defaults = bandit.plugins.insecure_ssl_tls:ssl_with_bad_defaults
ssl_with_no_version = bandit.plugins.insecure_ssl_tls:ssl_with_no_version
# bandit/plugins/jinja2_templates.py
jinja2_autoescape_false = bandit.plugins.jinja2_templates:jinja2_autoescape_false
# bandit/plugins/mako_templates.py
use_of_mako_templates = bandit.plugins.mako_templates:use_of_mako_templates
# bandit/plugins/secret_config_options.py
password_config_option_not_marked_secret = bandit.plugins.secret_config_option:password_config_option_not_marked_secret
# bandit/plugins/try_except_pass.py
try_except_pass = bandit.plugins.try_except_pass:try_except_pass
# bandit/plugins/xlm.py
etree_celement_function_calls = bandit.plugins.xml:etree_celement_function_calls
etree_element_function_calls = bandit.plugins.xml:etree_element_function_calls
expatreader_function_calls = bandit.plugins.xml:expatreader_function_calls
expatbuilder_function_calls = bandit.plugins.xml:expatbuilder_function_calls
sax_function_calls = bandit.plugins.xml:sax_function_calls
minidom_function_calls = bandit.plugins.xml:minidom_function_calls
pulldom_function_calls = bandit.plugins.xml:pulldom_function_calls
lxml_function_calls = bandit.plugins.xml:lxml_function_calls
etree_celement_import = bandit.plugins.xml:etree_celement_import
etree_element_import = bandit.plugins.xml:etree_element_import
expatreader_import = bandit.plugins.xml:expatreader_import
expatbuilder_import = bandit.plugins.xml:expatbuilder_import
sax_import = bandit.plugins.xml:sax_import
minidom_import = bandit.plugins.xml:minidom_import
pulldom_import = bandit.plugins.xml:pulldom_import
xmlrpclib_import = bandit.plugins.xml:xmlrpclib_import
lxml_import = bandit.plugins.xml:lxml_import
[files]
package_data =