From e025404e69c86450dcb8df02698f318239787ff0 Mon Sep 17 00:00:00 2001 From: Eric Brown Date: Fri, 1 May 2015 23:52:34 -0700 Subject: [PATCH] Add bandit for security static analysis testing This change adds a basic bandit config for Nova. It can be invoked by running the tox environment for bandit; tox -e bandit This is intended as a starting point for using bandit with Nova and it should be revisited to improve the testing as more is learned about the specific needs of the Nova code base. Tox is configured to only show results for high and medium severity results. https://wiki.openstack.org/wiki/Security/Projects/Bandit Change-Id: I3026b81317f0a6322acfc94784899a7453af586f --- bandit.yaml | 129 ++++++++++++++++++++++++++++++++++++++++++ test-requirements.txt | 1 + tox.ini | 4 ++ 3 files changed, 134 insertions(+) create mode 100644 bandit.yaml diff --git a/bandit.yaml b/bandit.yaml new file mode 100644 index 000000000000..69e2cea845dc --- /dev/null +++ b/bandit.yaml @@ -0,0 +1,129 @@ +# 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' + +# optional: log format string +#log_format: "[%(module)s]\t%(levelname)s\t%(message)s" + +# globs of files which should be analyzed +include: + - '*.py' + +# a list of strings, which if found in the path will cause files to be excluded +# for example /tests/ - to remove all all files in tests directory +exclude_dirs: + - '/tests/' + +profiles: + XSS: + include: + - jinja2_autoescape_false + - use_of_mako_templates + + ShellInjection: + include: + - subprocess_popen_with_shell_equals_true + - subprocess_without_shell_equals_true + - any_other_function_with_shell_equals_true + - start_process_with_a_shell + - start_process_with_no_shell + exclude: + + SqlInjection: + include: + - hardcoded_sql_expressions + +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] + message: "Use of insecure MD5 hash function." + - 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] + 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.urlretrieve, urllib.URLopener, urllib.FancyURLopener, urllib2.urlopen, urllib2.Request] + message: "Audit url open for permitted schemes. Allowing use of file:/ or custom schemes is often unexpected." + - paramiko_injection: + qualnames: [paramiko.exec_command, paramiko.invoke_shell] + message: "Paramiko exec_command() and invoke_shell() usage may expose command injection vulnerabilities and should be reviewed." + +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: "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." + +hardcoded_password: + word_list: "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: + - nova.utils.execute + - nova.utils.trycmd diff --git a/test-requirements.txt b/test-requirements.txt index d088001cc430..294ecf205581 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -21,6 +21,7 @@ oslotest>=1.5.1 # Apache-2.0 testrepository>=0.0.18 testtools>=1.4.0 tempest-lib>=0.6.1 +bandit>=0.10.1 # vmwareapi driver specific dependencies oslo.vmware>=0.13.1 # Apache-2.0 diff --git a/tox.ini b/tox.ini index 5e55830aeb63..3154344a6f89 100644 --- a/tox.ini +++ b/tox.ini @@ -79,6 +79,10 @@ commands = python setup.py build_sphinx bash -c '! find doc/ -type f -name *.json | xargs -t -n1 python -m json.tool 2>&1 > /dev/null | grep -B1 -v ^python' +[testenv:bandit] +deps = -r{toxinidir}/test-requirements.txt +commands = bandit -c bandit.yaml -r nova -n 5 -ll + [flake8] # E125 is deliberately excluded. See https://github.com/jcrocholl/pep8/issues/126 # The rest of the ignores are TODOs