From 63741c9c6bbd0720f6799d9fd5e9983239bb7861 Mon Sep 17 00:00:00 2001 From: Brant Knudson Date: Tue, 9 Feb 2016 16:50:05 -0600 Subject: [PATCH] Switch to configless bandit The 0.17.3 release of bandit supports running with no config, enabling all the tests with a default configuration for them, switch to that since it's easier to maintain. Change-Id: I507b7a11e8d1d69a6d9ec88493cbefe48be5ddcf --- bandit.yaml | 387 ------------------------ keystone/common/environment/__init__.py | 3 +- keystone/common/openssl.py | 7 +- tox.ini | 4 +- 4 files changed, 9 insertions(+), 392 deletions(-) delete mode 100644 bandit.yaml diff --git a/bandit.yaml b/bandit.yaml deleted file mode 100644 index 183661488c..0000000000 --- a/bandit.yaml +++ /dev/null @@ -1,387 +0,0 @@ -# optional: after how many files to update progress -#show_progress_every: 100 - -# optional: plugins directory name -#plugins_dir: plugins - -# optional: plugins discovery name pattern -plugin_name_pattern: '*.py' - -# optional: terminal escape sequences to display colors -#output_colors: -# DEFAULT: \033[0m -# HEADER: \033[95m -# LOW: \033[94m -# MEDIUM: \033[93m -# HIGH: \033[91m - -# globs of files which should be analyzed -include: - - '*.py' - - '*.pyw' - -# a list of strings, which if found in the path will cause files to be excluded -# for example /tests/ - to remove all files in tests directory -exclude_dirs: - - '/tests/' - -profiles: - gate: - include: - - any_other_function_with_shell_equals_true - - assert_used - - blacklist_calls - - blacklist_import_func - - # One of the blacklisted imports is the subprocess module. Keystone - # has to import the subprocess module in a single module for - # eventlet support so in most cases bandit won't be able to detect - # that subprocess is even being imported. Also, Bandit's - # recommendation is just to check that the use is safe without any - # documentation on what safe or unsafe usage is. So this test is - # skipped. - # - blacklist_imports - - - exec_used - - # Keystone doesn't use rootwrap and never will. - # - execute_with_run_as_root_equals_true - - - hardcoded_bind_all_interfaces - - hardcoded_password_string - - hardcoded_password_funcarg - - hardcoded_password_default - - # Not used because it's prone to false positives: - # - hardcoded_sql_expressions - - - hardcoded_tmp_directory - - # Keystone has no use for jinja2. - # - jinja2_autoescape_false - - - linux_commands_wildcard_injection - - # Keystone has no use for paramiko. - # - paramiko_calls - - - password_config_option_not_marked_secret - - request_with_no_cert_validation - - set_bad_file_permissions - - subprocess_popen_with_shell_equals_true - - subprocess_without_shell_equals_true - - start_process_with_a_shell - - start_process_with_no_shell - - start_process_with_partial_path - - ssl_with_bad_defaults - - ssl_with_bad_version - - ssl_with_no_version - - try_except_pass - - # Keystone has no use for mako. - # - use_of_mako_templates - - - weak_cryptographic_key - -blacklist_calls: - bad_name_sets: - - pickle: - qualnames: - - pickle.loads - - pickle.load - - pickle.Unpickler - - cPickle.loads - - cPickle.load - - cPickle.Unpickler - message: > - Pickle library appears to be in use, possible security issue. - - marshal: - qualnames: - - marshal.load - - marshal.loads - message: > - Deserialization with the marshal module is possibly dangerous. - - md5: - qualnames: - - hashlib.md5 - - Crypto.Hash.MD2.new - - Crypto.Hash.MD4.new - - Crypto.Hash.MD5.new - - cryptography.hazmat.primitives.hashes.MD5 - message: Use of insecure MD2, MD4, or MD5 hash function. - - ciphers: - qualnames: - - Crypto.Cipher.ARC2.new - - Crypto.Cipher.ARC4.new - - Crypto.Cipher.Blowfish.new - - Crypto.Cipher.DES.new - - Crypto.Cipher.XOR.new - - cryptography.hazmat.primitives.ciphers.algorithms.ARC4 - - cryptography.hazmat.primitives.ciphers.algorithms.Blowfish - - cryptography.hazmat.primitives.ciphers.algorithms.IDEA - message: > - Use of insecure cipher {func}. Replace with a known secure - cipher such as AES. - level: HIGH - - cipher_modes: - qualnames: - - cryptography.hazmat.primitives.ciphers.modes.ECB - message: Use of insecure cipher mode {func}. - - mktemp_q: - qualnames: [tempfile.mktemp] - message: Use of insecure and deprecated function (mktemp). - - eval: - qualnames: [eval] - message: > - Use of possibly insecure function - consider using safer - ast.literal_eval. - - mark_safe: - names: [mark_safe] - message: > - Use of mark_safe() may expose cross-site scripting - vulnerabilities and should be reviewed. - - httpsconnection: - qualnames: - - httplib.HTTPSConnection - - http.client.HTTPSConnection - - six.moves.http_client.HTTPSConnection - message: > - Use of HTTPSConnection does not provide security, see - https://wiki.openstack.org/wiki/OSSN/OSSN-0033 - - yaml_load: - qualnames: [yaml.load] - message: > - Use of unsafe yaml load. Allows instantiation of arbitrary - objects. Consider yaml.safe_load(). - - urllib_urlopen: - qualnames: - - urllib.urlopen - - urllib.request.urlopen - - urllib.urlretrieve - - urllib.request.urlretrieve - - urllib.URLopener - - urllib.request.URLopener - - urllib.FancyURLopener - - urllib.request.FancyURLopener - - urllib2.urlopen - - urllib2.Request - - six.moves.urllib.request.urlopen - - six.moves.urllib.request.urlretrieve - - six.moves.urllib.request.URLopener - - six.moves.urllib.request.FancyURLopener - message: > - Audit url open for permitted schemes. Allowing use of file:/ or - custom schemes is often unexpected. - - random: - qualnames: - - random.random - - random.randrange - - random.randint - - random.choice - - random.uniform - - random.triangular - message: > - Standard pseudo-random generators are not suitable for - security/cryptographic purposes. - level: LOW - - telnetlib: - qualnames: - - telnetlib.* - message: > - Telnet-related funtions are being called. Telnet is considered - insecure. Use SSH or some other encrypted protocol. - level: HIGH - # Most of this is based off of Christian Heimes' work on defusedxml: - # https://pypi.python.org/pypi/defusedxml/#defusedxml-sax - - xml_bad_cElementTree: - qualnames: - - xml.etree.cElementTree.parse - - xml.etree.cElementTree.iterparse - - xml.etree.cElementTree.fromstring - - xml.etree.cElementTree.XMLParser - message: > - Using {func} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {func} with its defusedxml - equivalent function. - - xml_bad_ElementTree: - qualnames: - - xml.etree.ElementTree.parse - - xml.etree.ElementTree.iterparse - - xml.etree.ElementTree.fromstring - - xml.etree.ElementTree.XMLParser - message: > - Using {func} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {func} with its defusedxml - equivalent function. - - xml_bad_expatreader: - qualnames: [xml.sax.expatreader.create_parser] - message: > - Using {func} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {func} with its defusedxml - equivalent function. - - xml_bad_expatbuilder: - qualnames: - - xml.dom.expatbuilder.parse - - xml.dom.expatbuilder.parseString - message: > - Using {func} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {func} with its defusedxml - equivalent function. - - xml_bad_sax: - qualnames: - - xml.sax.parse - - xml.sax.parseString - - xml.sax.make_parser - message: > - Using {func} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {func} with its defusedxml - equivalent function. - - xml_bad_minidom: - qualnames: - - xml.dom.minidom.parse - - xml.dom.minidom.parseString - message: > - Using {func} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {func} with its defusedxml - equivalent function. - - xml_bad_pulldom: - qualnames: - - xml.dom.pulldom.parse - - xml.dom.pulldom.parseString - message: > - Using {func} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {func} with its defusedxml - equivalent function. - - xml_bad_etree: - qualnames: - - lxml.etree.parse - - lxml.etree.fromstring - - lxml.etree.RestrictedElement - - lxml.etree.GlobalParserTLS - - lxml.etree.getDefaultParser - - lxml.etree.check_docinfo - message: > - Using {func} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {func} with its defusedxml - equivalent function. - - -shell_injection: - # Start a process using the subprocess module, or one of its wrappers. - subprocess: - - subprocess.Popen - - subprocess.call - - subprocess.check_call - - subprocess.check_output - - utils.execute - - utils.execute_with_timeout - # Start a process with a function vulnerable to shell injection. - shell: - - os.system - - os.popen - - os.popen2 - - os.popen3 - - os.popen4 - - popen2.popen2 - - popen2.popen3 - - popen2.popen4 - - popen2.Popen3 - - popen2.Popen4 - - commands.getoutput - - commands.getstatusoutput - # Start a process with a function that is not vulnerable to shell injection. - no_shell: - - os.execl - - os.execle - - os.execlp - - os.execlpe - - os.execv - - os.execve - - os.execvp - - os.execvpe - - os.spawnl - - os.spawnle - - os.spawnlp - - os.spawnlpe - - os.spawnv - - os.spawnve - - os.spawnvp - - os.spawnvpe - - os.startfile - -blacklist_imports: - bad_import_sets: - - telnet: - imports: [telnetlib] - level: HIGH - message: > - A telnet-related module is being imported. Telnet is - considered insecure. Use SSH or some other encrypted protocol. - - info_libs: - imports: [pickle, cPickle, subprocess, Crypto] - level: LOW - message: > - Consider possible security implications associated with - {module} module. - - # Most of this is based off of Christian Heimes' work on defusedxml: - # https://pypi.python.org/pypi/defusedxml/#defusedxml-sax - - - xml_libs: - imports: - - xml.etree.cElementTree - - xml.etree.ElementTree - - xml.sax.expatreader - - xml.sax - - xml.dom.expatbuilder - - xml.dom.minidom - - xml.dom.pulldom - - lxml.etree - - lxml - message: > - Using {module} to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace {module} with the equivalent - defusedxml package. - level: LOW - - xml_libs_high: - imports: [xmlrpclib] - message: > - Using {module} to parse untrusted XML data is known to be - vulnerable to XML attacks. Use defused.xmlrpc.monkey_patch() - function to monkey-patch xmlrpclib and mitigate XML - vulnerabilities. - level: HIGH - -hardcoded_tmp_directory: - tmp_dirs: [/tmp, /var/tmp, /dev/shm] - -hardcoded_password: - # 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: - - PROTOCOL_SSLv2 - - SSLv2_METHOD - - SSLv23_METHOD - - PROTOCOL_SSLv3 # strict option - - PROTOCOL_TLSv1 # strict option - - SSLv3_METHOD # strict option - - TLSv1_METHOD # strict option - -password_config_option_not_marked_secret: - function_names: - - oslo.config.cfg.StrOpt - - oslo_config.cfg.StrOpt - -execute_with_run_as_root_equals_true: - function_names: - - ceilometer.utils.execute - - cinder.utils.execute - - neutron.agent.linux.utils.execute - - nova.utils.execute - - nova.utils.trycmd - -try_except_pass: - check_typed_exception: True diff --git a/keystone/common/environment/__init__.py b/keystone/common/environment/__init__.py index 4e08eb4bf2..6748f11542 100644 --- a/keystone/common/environment/__init__.py +++ b/keystone/common/environment/__init__.py @@ -95,7 +95,8 @@ def use_stdlib(): global httplib, subprocess import six.moves.http_client as _httplib - import subprocess as _subprocess + import subprocess as _subprocess # nosec : This is used in .federation.idp + # and .common.openssl. See there. httplib = _httplib subprocess = _subprocess diff --git a/keystone/common/openssl.py b/keystone/common/openssl.py index 7095bc579b..91a6db83dc 100644 --- a/keystone/common/openssl.py +++ b/keystone/common/openssl.py @@ -65,7 +65,8 @@ class BaseCertificateConfigure(object): try: # OpenSSL 1.0 and newer support default_md = default, # older versions do not - openssl_ver = environment.subprocess.check_output( + openssl_ver = environment.subprocess.check_output( # the arguments + # are hardcoded and just check the openssl version ['openssl', 'version']) if "OpenSSL 0." in openssl_ver: self.ssl_dictionary['default_md'] = 'sha1' @@ -80,7 +81,9 @@ class BaseCertificateConfigure(object): try: # NOTE(shaleh): use check_output instead of the simpler # `check_call()` in order to log any output from an error. - environment.subprocess.check_output( + environment.subprocess.check_output( # the arguments being passed + # in are defined in this file and trusted to build CAs, keys + # and certs to_exec, stderr=environment.subprocess.STDOUT) except environment.subprocess.CalledProcessError as e: diff --git a/tox.ini b/tox.ini index a6e39636a4..b79588f287 100644 --- a/tox.ini +++ b/tox.ini @@ -44,13 +44,13 @@ commands = bash -c "find keystone -type f -regex '.*\.pot?' -print0| \ xargs -0 -n 1 msgfmt --check-format -o /dev/null" # Run security linter - bandit -c bandit.yaml -r keystone -n5 -p gate + bandit -r keystone [testenv:bandit] # NOTE(browne): This is required for the integration test job of the bandit # project. Please do not remove. deps = .[bandit] -commands = bandit -c bandit.yaml -r keystone -n5 -p gate +commands = bandit -r keystone [testenv:cover] commands = python setup.py testr --coverage --testr-args='{posargs}'