diff --git a/.gitignore b/.gitignore index bcd88f2f..bf13380f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,8 @@ venv* build/* cover/* .coverage -docs/build/* +doc/build/* ChangeLog -docs/source/api +doc/source/api .*.sw? AUTHORS diff --git a/bandit/plugins/app_debug.py b/bandit/plugins/app_debug.py index 13e2c37f..c90fb65e 100644 --- a/bandit/plugins/app_debug.py +++ b/bandit/plugins/app_debug.py @@ -14,6 +14,43 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Running Flask applications in debug mode results in the Werkzeug debugger +being enabled. This includes a feature that allows arbitrary code execution. +Documentation for both Flask [1]_ and Werkzeug [2]_ strongly suggests that +debug mode should never be enabled on production systems. + +Operating a production server with debug mode enabled was the probable cause +of the Patreon breach in 2015 [3]_. + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: A Flask app appears to be run with debug=True, which exposes + the Werkzeug debugger and allows the execution of arbitrary code. + Severity: High Confidence: High + Location: examples/flask_debug.py:10 + 9 #bad + 10 app.run(debug=True) + 11 + +References +---------- +.. [1] http://flask.pocoo.org/docs/0.10/quickstart/#debug-mode +.. [2] http://werkzeug.pocoo.org/docs/0.10/debug/ +.. [3] http://labs.detectify.com/post/130332638391/how-patreon-got-hacked-publicly-exposed-werkzeug # noqa + +.. versionadded:: 0.15.0 + +""" + import bandit from bandit.core.test_properties import checks diff --git a/bandit/plugins/asserts.py b/bandit/plugins/asserts.py index 4f0ab6e9..245b9863 100644 --- a/bandit/plugins/asserts.py +++ b/bandit/plugins/asserts.py @@ -14,6 +14,44 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +This plugin test checks for the use of the Python ``assert`` keyword. It was +discovered that some projects used assert to enforce interface constraints. +However, assert is removed with compiling to optimised byte code (python -o +producing \*.pyo files). This caused various protections to be removed. The use +of assert is also considered as general bad practice in OpenStack codebases. + +Please see +https://docs.python.org/2/reference/simple_stmts.html#the-assert-statement for +more info on ``assert`` + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: Use of assert detected. The enclosed code will be removed when + compiling to optimised byte code. + Severity: Low Confidence: High + Location: ./examples/assert.py:1 + 1 assert logged_in + 2 display_assets() + +References +---------- + - https://bugs.launchpad.net/juniperopenstack/+bug/1456193 + - https://bugs.launchpad.net/heat/+bug/1397883 + - https://docs.python.org/2/reference/simple_stmts.html#the-assert-statement + +.. versionadded:: 0.11.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/bandit/plugins/blacklist_calls.py b/bandit/plugins/blacklist_calls.py index 68fee7e3..5cd3375c 100644 --- a/bandit/plugins/blacklist_calls.py +++ b/bandit/plugins/blacklist_calls.py @@ -14,6 +14,76 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +A number of Python methods and functions are known to have potential security +implications. The blacklist calls plugin test is designed to detect the use of +these methods by scanning code for method calls and checking for their presence +in a configurable blacklist. The scanned calls are fully qualified and +de-aliased prior to checking. To illustrate this, imagine a check for +"evil.thing()" running on the following example code: + +.. code-block:: python + + import evil as good + + good.thing() + thing() + +This would generate a warning about calling `evil.thing()` despite the module +being aliased as `good`. It would also not generate a warning on the call to +`thing()` in the local module, as it's fully qualified name will not match. + +Each of the provided blacklisted calls can be grouped such that they generate +appropriate warnings (message, severity) and a token `{func}` may be used +in the provided output message, to be replaced with the actual method name. + +Due to the nature of the test, confidence is always reported as HIGH + +Config Options +-------------- +.. code-block:: yaml + + 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 {func} is possibly dangerous. + level: LOW + +Sample Output +------------- +.. code-block:: none + + >> Issue: Pickle library appears to be in use, possible security issue. + + Severity: Medium Confidence: High + Location: ./examples/pickle_deserialize.py:20 + 19 serialized = cPickle.dumps({(): []}) + 20 print(cPickle.loads(serialized)) + 21 + +References +---------- +- https://security.openstack.org + +.. versionadded:: 0.9.0 + +""" + import fnmatch import bandit diff --git a/bandit/plugins/blacklist_imports.py b/bandit/plugins/blacklist_imports.py index 5962a541..a1623d0b 100644 --- a/bandit/plugins/blacklist_imports.py +++ b/bandit/plugins/blacklist_imports.py @@ -14,7 +14,6 @@ # License for the specific language governing permissions and limitations # under the License. - import bandit from bandit.core.test_properties import * @@ -22,6 +21,89 @@ from bandit.core.test_properties import * @takes_config @checks('Import', 'ImportFrom') def blacklist_imports(context, config): + """blacklist_imports + + A number of Python modules are known to provide collections of + functionality with potential security implications. The blacklist imports + plugin test is designed to detect the use of these modules by scanning code + for `import` statements and checking for the imported modules presence in a + configurable blacklist. The imported modules are fully qualified and + de-aliased prior to checking. To illustrate this, imagine a check for + "module.evil" running on the following example code: + + .. code-block:: python + + import module # no warning + import module.evil # warning + from module import evil # warning + from module import evil as good # warning + + This would generate a warning about importing `module.evil` in each of the + last three cases, despite the module being aliased as `good` in one of + them. It would also not generate a warning on the first import + (of `module`) as it's fully qualified name will not match. + + Each of the provided blacklisted modules can be grouped such that they + generate appropriate warnings (message, severity) and a token `{module}` + may be used in the provided output message, to be replaced with the actual + module name. + + Due to the nature of the test, confidence is always reported as HIGH + + Config Options: + + .. code-block:: yaml + + blacklist_imports: + bad_import_sets: + - 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 + + + Sample Output: + + .. code-block:: none + + >> Issue: Using xml.sax to parse untrusted XML data is known to be + vulnerable to XML attacks. Replace xml.sax with the equivalent + defusedxml package. + + Severity: Low Confidence: High + Location: ./examples/xml_sax.py:1 + 1 import xml.sax + 2 from xml import sax + + >> Issue: Using xml.sax.parseString to parse untrusted XML data is + known to be vulnerable to XML attacks. Replace xml.sax.parseString with + its defusedxml equivalent function. + + Severity: Medium Confidence: High + Location: ./examples/xml_sax.py:21 + 20 # bad + 21 xml.sax.parseString(xmlString, ExampleContentHandler()) + 22 xml.sax.parse('notaxmlfilethatexists.xml', ExampleContentHandler()) + + References: + + - https://security.openstack.org + + .. versionadded:: 0.9.0 + """ + checks = _load_checks(config) # for each check, go through and see if it matches all qualifications @@ -36,6 +118,52 @@ def blacklist_imports(context, config): @takes_config('blacklist_imports') @checks('Call') def blacklist_import_func(context, config): + """blacklist_import_func + + This test is in all ways identical blacklist_imports. However, it + is designed to catch modules that have been imported using Python's special + builtin import function, `__import__()`. For example, running a test on the + following code for `module.evil` would warn as shown: + + .. code-block:: python + + __import__('module') # no warning + __import__('module.evil') # warning + + This test shares the configuration provided for the standard + blacklist_imports test. + + + Sample Output: + + .. code-block:: none + + >> Issue: Using xml.sax to parse untrusted XML data is known to be + vulnerable to XML attacks. Replace xml.sax with the equivalent + defusedxml package. + + Severity: Low Confidence: High + Location: ./examples/xml_sax.py:1 + 1 import xml.sax + 2 from xml import sax + + >> Issue: Using xml.sax.parseString to parse untrusted XML data is + known to be vulnerable to XML attacks. Replace xml.sax.parseString with + its defusedxml equivalent function. + + Severity: Medium Confidence: High + Location: ./examples/xml_sax.py:21 + 20 # bad + 21 xml.sax.parseString(xmlString, ExampleContentHandler()) + 22 xml.sax.parse('notaxmlfilethatexists.xml', ExampleContentHandler()) + + + References: + + - https://security.openstack.org + + .. versionadded:: 0.9.0 + """ checks = _load_checks(config) if context.call_function_name_qual == '__import__': for check in checks: diff --git a/bandit/plugins/crypto_request_no_cert_validation.py b/bandit/plugins/crypto_request_no_cert_validation.py index d982d949..e8c0e72b 100644 --- a/bandit/plugins/crypto_request_no_cert_validation.py +++ b/bandit/plugins/crypto_request_no_cert_validation.py @@ -14,6 +14,44 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Encryption in general is typically critical to the security of many +applications. Using TLS can greatly increase security by guaranteeing the +identity of the party you are communicating with. This is accomplished by one +or both parties presenting trusted certificates during the connection +initialization phase of TLS. + +When request methods are used certificates are validated automatically which is +the desired behavior. If certificate validation is explicitly turned off +Bandit will return a HIGH severity error. + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: [request_with_no_cert_validation] Requests call with verify=False + disabling SSL certificate checks, security issue. + Severity: High Confidence: High + Location: examples/requests-ssl-verify-disabled.py:4 + 3 requests.get('https://gmail.com', verify=True) + 4 requests.get('https://gmail.com', verify=False) + 5 requests.post('https://gmail.com', verify=True) + +References +---------- +- https://security.openstack.org/guidelines/dg_move-data-securely.html +- https://security.openstack.org/guidelines/dg_validate-certificates.html + +.. versionadded:: 0.9.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/bandit/plugins/exec.py b/bandit/plugins/exec.py index 3e55c9d8..6ce777bd 100644 --- a/bandit/plugins/exec.py +++ b/bandit/plugins/exec.py @@ -13,6 +13,35 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + +r""" +Description +----------- +This plugin test checks for the use of Python's `exec` method or keyword. The +Python docs succinctly describe why the use of `exec` is risky. + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: Use of exec detected. + Severity: Medium Confidence: High + Location: ./examples/exec-py2.py:2 + 1 exec("do evil") + 2 exec "do evil" + +References +---------- + - https://docs.python.org/2.0/ref/exec.html + - TODO: add info on exec and similar to sec best practice and link here + +.. versionadded:: 0.9.0 +""" + import six import bandit diff --git a/bandit/plugins/exec_as_root.py b/bandit/plugins/exec_as_root.py index 5763da37..88329f44 100644 --- a/bandit/plugins/exec_as_root.py +++ b/bandit/plugins/exec_as_root.py @@ -12,6 +12,56 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Running commands as root dramatically increase their potential risk. Running +commands with restricted user privileges provides defense in depth against +command injection attacks, or developer and configuration error. This plugin +test checks for specific methods being called with a keyword parameter +`run_as_root` set to True, a common OpenStack idiom. + + +Config Options +-------------- +This test plugin takes a similarly named configuration block, +`execute_with_run_as_root_equals_true`, providing a list, `function_names`, of +function names. A call to any of these named functions will be checked for a +`run_as_root` keyword parameter, and if True, will report a Low severity +issue. + +.. code-block:: yaml + + 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 + + +Sample Output +------------- +.. code-block:: none + + >> Issue: Execute with run_as_root=True identified, possible security + issue. + Severity: Low Confidence: Medium + Location: ./examples/exec-as-root.py:26 + 25 nova_utils.trycmd('gcc --version') + 26 nova_utils.trycmd('gcc --version', run_as_root=True) + 27 + +References +---------- + - https://security.openstack.org/guidelines/dg_rootwrap-recommendations-and-plans.html # noqa + - https://security.openstack.org/guidelines/dg_use-oslo-rootwrap-securely.html + +.. versionadded:: 0.10.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/bandit/plugins/general_bad_file_permissions.py b/bandit/plugins/general_bad_file_permissions.py index 5a39c00d..7a14d82b 100644 --- a/bandit/plugins/general_bad_file_permissions.py +++ b/bandit/plugins/general_bad_file_permissions.py @@ -14,6 +14,51 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +POSIX based operating systems utilize a permissions model to protect access to +parts of the file system. This model supports three roles "owner", "group" +and "world" each role may have a combination of "read", "write" or "execute" +flags sets. Python provides ``chmod`` to manipulate POSIX style permissions. + +This plugin test looks for the use of ``chmod`` and will alert when it is used +to set particularly permissive control flags. A MEDIUM warning is generated if +a file is set to group executable and a HIGH warning is reported if a file is +set world writable. Warnings are given with HIGH confidence. + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: Probable insecure usage of temp file/directory. + Severity: Medium Confidence: Medium + Location: ./examples/os-chmod-py2.py:15 + 14 os.chmod('/etc/hosts', 0o777) + 15 os.chmod('/tmp/oh_hai', 0x1ff) + 16 os.chmod('/etc/passwd', stat.S_IRWXU) + + >> Issue: Chmod setting a permissive mask 0777 on file (key_file). + Severity: High Confidence: High + Location: ./examples/os-chmod-py2.py:17 + 16 os.chmod('/etc/passwd', stat.S_IRWXU) + 17 os.chmod(key_file, 0o777) + 18 + +References +---------- +- https://security.openstack.org/guidelines/dg_apply-restrictive-file-permissions.html # noqa +- https://en.wikipedia.org/wiki/File_system_permissions +- https://security.openstack.org + +.. versionadded:: 0.9.0 + +""" + import stat import bandit diff --git a/bandit/plugins/general_bind_all_interfaces.py b/bandit/plugins/general_bind_all_interfaces.py index 97a811fc..229f03b7 100644 --- a/bandit/plugins/general_bind_all_interfaces.py +++ b/bandit/plugins/general_bind_all_interfaces.py @@ -14,6 +14,38 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Binding to all network interfaces can potentially open up a service to traffic +on unintended interfaces, that may not be properly documented or secured. This +plugin test looks for a string pattern "0.0.0.0" that may indicate a hardcoded +binding to all network interfaces. + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: Possible binding to all interfaces. + Severity: Medium Confidence: Medium + Location: ./examples/binding.py:4 + 3 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + 4 s.bind(('0.0.0.0', 31137)) + 5 s.bind(('192.168.0.1', 8080)) + +References +---------- + - __TODO__ : add best practice info on binding to all interfaces, and link + here. + +.. versionadded:: 0.9.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/bandit/plugins/general_hardcoded_password.py b/bandit/plugins/general_hardcoded_password.py index 2915066f..b5e2e972 100644 --- a/bandit/plugins/general_hardcoded_password.py +++ b/bandit/plugins/general_hardcoded_password.py @@ -14,6 +14,49 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +The use of hard-coded passwords increases the possibility of password guessing +tremendously. This plugin test looks for all string literals and checks to see +if they exist in a list of likely default passwords. If they are found in the +list, a LOW severity issue is reported. + +Note: this test is very noisy and likely to result in many false positives. + +Config Options +-------------- +This plugin test takes a similarly named config block, `hardcoded_password`. +Here a path, `word_list`, can be given to indicate where the default password +word list file may be found. + +.. code-block:: yaml + + 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" + + +Sample Output +------------- +.. code-block:: none + + >> Issue: Possible hardcoded password '(root)' + Severity: Low Confidence: Low + Location: ./examples/hardcoded-passwords.py:5 + 4 def someFunction2(password): + 5 if password == "root": + 6 print("OK, logged in") + +References +---------- +- https://www.owasp.org/index.php/Use_of_hard-coded_password + +.. versionadded:: 0.9.0 + +""" + import sys import bandit diff --git a/bandit/plugins/general_hardcoded_tmp.py b/bandit/plugins/general_hardcoded_tmp.py index eb54f86b..5ad62619 100644 --- a/bandit/plugins/general_hardcoded_tmp.py +++ b/bandit/plugins/general_hardcoded_tmp.py @@ -14,6 +14,50 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Safely creating a temporary file or directory means following a number of rules +(see the references for more details). This plugin test looks for strings +starting with (configurable) commonly used temporary paths, for example: + + - /tmp + - /var/tmp + - /dev/shm + - etc + +Config Options +-------------- +This test plugin takes a similarly named config block, +`hardcoded_tmp_directory`. The config block provides a Python list, `tmp_dirs`, +that lists string fragments indicating possible temporary file paths. Any +string starting with one of these fragments will report a MEDIUM confidence +issue. + +.. code-block:: yaml + + hardcoded_tmp_directory: + tmp_dirs: ['/tmp', '/var/tmp', '/dev/shm'] + + +Sample Output +------------- +.. code-block: none + + >> Issue: Probable insecure usage of temp file/directory. + Severity: Medium Confidence: Medium + Location: ./examples/hardcoded-tmp.py:1 + 1 f = open('/tmp/abc', 'w') + 2 f.write('def') + +References +---------- + - https://security.openstack.org/guidelines/dg_using-temporary-files-securely.html # noqa + +.. versionadded:: 0.9.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/bandit/plugins/injection_paramiko.py b/bandit/plugins/injection_paramiko.py index 57ce92d7..8a760668 100644 --- a/bandit/plugins/injection_paramiko.py +++ b/bandit/plugins/injection_paramiko.py @@ -14,6 +14,53 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Paramiko is a Python library designed to work with the SSH2 protocol for secure +(encrypted and authenticated) connections to remote machines. It is intended to +run commands on a remote host. These commands are run within a shell on the +target and are thus vulnerable to various shell injection attacks. Bandit +reports a MEDIUM issue when it detects the use of Paramiko's "exec_command" or +"invoke_shell" methods advising the user to check inputs are correctly +sanitized. + + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: Possible shell injection via Paramiko call, check inputs are + properly sanitized. + Severity: Medium Confidence: Medium + Location: ./examples/paramiko_injection.py:4 + 3 # this is not safe + 4 paramiko.exec_command('something; reallly; unsafe') + 5 + + >> Issue: Possible shell injection via Paramiko call, check inputs are + properly sanitized. + Severity: Medium Confidence: Medium + Location: ./examples/paramiko_injection.py:10 + 9 # this is not safe + 10 SSHClient.invoke_shell('something; bad; here\n') + 11 + +References +---------- + +- https://security.openstack.org +- https://github.com/paramiko/paramiko +- https://www.owasp.org/index.php/Command_Injection + +.. versionadded:: 0.12.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/bandit/plugins/injection_shell.py b/bandit/plugins/injection_shell.py index edbac57b..72144157 100644 --- a/bandit/plugins/injection_shell.py +++ b/bandit/plugins/injection_shell.py @@ -50,6 +50,96 @@ def _evaluate_shell_call(context): @takes_config('shell_injection') @checks('Call') def subprocess_popen_with_shell_equals_true(context, config): + """subprocess_popen_with_shell_equals_true + + Python possesses many mechanisms to invoke an external executable. However, + doing so may present a security issue if appropriate care is not taken to + sanitize any user provided or variable input. + + This plugin test is part of a family of tests built to check for process + spawning and warn appropriately. Specifically, this test looks for the + spawning of a subprocess using a command shell. This type of subprocess + invocation is dangerous as it is vulnerable to various shell injection + attacks. Great care should be taken to sanitize all input in order to + mitigate this risk. Calls of this type are identified by a parameter of + "shell=True" being given. + + Additionally, this plugin scans the command string given and adjusts its + reported severity based on how it is presented. If the command string is a + simple static string containing no special shell characters, then the + resulting issue has low severity. If the string is static, but contains + shell formatting characters or wildcards, then the reported issue is + medium. Finally, if the string is computed using Python's string + manipulation or formatting operations, then the reported issue has high + severity. These severity levels reflect the likelihood that the code is + vulnerable to injection. + + See also: + + - :doc:`../plugins/linux_commands_wildcard_injection` + - :doc:`../plugins/subprocess_without_shell_equals_true` + - :doc:`../plugins/start_process_with_no_shell` + - :doc:`../plugins/start_process_with_a_shell` + - :doc:`../plugins/start_process_with_partial_path` + + Config Options: + + This plugin test shares a configuration with others in the same family, + namely `shell_injection`. This configuration is divided up into three + sections, `subprocess`, `shell` and `no_shell`. They each list Python calls + that spawn subprocesses, invoke commands within a shell, or invoke commands + without a shell (by replacing the calling process) respectively. + + This plugin specifically scans for methods listed in `subprocess` section + that have shell=True specified. + + .. code-block:: yaml + + shell_injection: + + # Start a process using the subprocess module, or one of its + wrappers. + subprocess: + - subprocess.Popen + - subprocess.call + + + Sample Output: + + .. code-block:: none + + >> Issue: subprocess call with shell=True seems safe, but may be + changed in the future, consider rewriting without shell + Severity: Low Confidence: High + Location: ./examples/subprocess_shell.py:21 + 20 subprocess.check_call(['/bin/ls', '-l'], shell=False) + 21 subprocess.check_call('/bin/ls -l', shell=True) + 22 + + >> Issue: call with shell=True contains special shell characters, + consider moving extra logic into Python code + Severity: Medium Confidence: High + Location: ./examples/subprocess_shell.py:26 + 25 + 26 subprocess.Popen('/bin/ls *', shell=True) + 27 subprocess.Popen('/bin/ls %s' % ('something',), shell=True) + + >> Issue: subprocess call with shell=True identified, security issue. + Severity: High Confidence: High + Location: ./examples/subprocess_shell.py:27 + 26 subprocess.Popen('/bin/ls *', shell=True) + 27 subprocess.Popen('/bin/ls %s' % ('something',), shell=True) + 28 subprocess.Popen('/bin/ls {}'.format('something'), shell=True) + + References: + + - https://security.openstack.org + - https://docs.python.org/2/library/subprocess.html#frequently-used-arguments # noqa + - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html + - https://security.openstack.org/guidelines/dg_avoid-shell-true.html + + .. versionadded:: 0.9.0 + """ if config and context.call_function_name_qual in config['subprocess']: if context.check_call_arg_value('shell', 'True'): if len(context.call_args) > 0: @@ -82,6 +172,71 @@ def subprocess_popen_with_shell_equals_true(context, config): @takes_config('shell_injection') @checks('Call') def subprocess_without_shell_equals_true(context, config): + """subprocess_without_shell_equals_true + + Python possesses many mechanisms to invoke an external executable. However, + doing so may present a security issue if appropriate care is not taken to + sanitize any user provided or variable input. + + This plugin test is part of a family of tests built to check for process + spawning and warn appropriately. Specifically, this test looks for the + spawning of a subprocess without the use of a command shell. This type of + subprocess invocation is not vulnerable to shell injection attacks, but + care should still be taken to ensure validity of input. + + Because this is a lesser issue than that described in + `subprocess_popen_with_shell_equals_true` a LOW severity warning is + reported. + + See also: + + - :doc:`../plugins/linux_commands_wildcard_injection` + - :doc:`../plugins/subprocess_popen_with_shell_equals_true` + - :doc:`../plugins/start_process_with_no_shell` + - :doc:`../plugins/start_process_with_a_shell` + - :doc:`../plugins/start_process_with_partial_path` + + Config Options: + + This plugin test shares a configuration with others in the same family, + namely `shell_injection`. This configuration is divided up into three + sections, `subprocess`, `shell` and `no_shell`. They each list Python calls + that spawn subprocesses, invoke commands within a shell, or invoke commands + without a shell (by replacing the calling process) respectively. + + This plugin specifically scans for methods listed in `subprocess` section + that have shell=False specified. + + .. code-block:: yaml + + shell_injection: + # Start a process using the subprocess module, or one of its + wrappers. + subprocess: + - subprocess.Popen + - subprocess.call + + + Sample Output: + + .. code-block:: none + + >> Issue: subprocess call - check for execution of untrusted input. + Severity: Low Confidence: High + Location: ./examples/subprocess_shell.py:23 + 22 + 23 subprocess.check_output(['/bin/ls', '-l']) + 24 + + References: + + - https://security.openstack.org + - https://docs.python.org/2/library/subprocess.html#frequently-used-arguments # noqa + - https://security.openstack.org/guidelines/dg_avoid-shell-true.html + - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html + + .. versionadded:: 0.9.0 + """ if config and context.call_function_name_qual in config['subprocess']: if not context.check_call_arg_value('shell', 'True'): return bandit.Issue( @@ -95,10 +250,73 @@ def subprocess_without_shell_equals_true(context, config): @takes_config('shell_injection') @checks('Call') def any_other_function_with_shell_equals_true(context, config): + """any_other_function_with_shell_equals_true + + Python possesses many mechanisms to invoke an external executable. However, + doing so may present a security issue if appropriate care is not taken to + sanitize any user provided or variable input. + + This plugin test is part of a family of tests built to check for process + spawning and warn appropriately. Specifically, this plugin test + interrogates method calls for the presence of a keyword parameter `shell` + equalling true. It is related to detection of shell injection issues and is + intended to catch custom wrappers to vulnerable methods that may have been + created. + + See also: + + - :doc:`../plugins/linux_commands_wildcard_injection` + - :doc:`../plugins/subprocess_popen_with_shell_equals_true` + - :doc:`../plugins/subprocess_without_shell_equals_true` + - :doc:`../plugins/start_process_with_no_shell` + - :doc:`../plugins/start_process_with_a_shell` + - :doc:`../plugins/start_process_with_partial_path` + + Config Options: + + This plugin test shares a configuration with others in the same family, + namely `shell_injection`. This configuration is divided up into three + sections, `subprocess`, `shell` and `no_shell`. They each list Python calls + that spawn subprocesses, invoke commands within a shell, or invoke commands + without a shell (by replacing the calling process) respectively. + + Specifically, this plugin excludes those functions listed under the + subprocess section, these methods are tested in a separate specific test + plugin and this exclusion prevents duplicate issue reporting. + + .. code-block:: yaml + + 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] + + + Sample Output: + + .. code-block:: none + + >> Issue: Function call with shell=True parameter identified, possible + security issue. + Severity: Medium Confidence: High + Location: ./examples/subprocess_shell.py:9 + 8 pop('/bin/gcc --version', shell=True) + 9 Popen('/bin/gcc --version', shell=True) + 10 + + References: + + - https://security.openstack.org/guidelines/dg_avoid-shell-true.html + - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html # noqa + """ '''Alerts on any function call that includes a shell=True parameter. Multiple "helpers" with varying names have been identified across various OpenStack projects. + + .. versionadded:: 0.9.0 ''' if config and context.call_function_name_qual not in config['subprocess']: if context.check_call_arg_value('shell', 'True'): @@ -113,6 +331,75 @@ def any_other_function_with_shell_equals_true(context, config): @takes_config('shell_injection') @checks('Call') def start_process_with_a_shell(context, config): + """start_process_with_a_shell + + Python possesses many mechanisms to invoke an external executable. However, + doing so may present a security issue if appropriate care is not taken to + sanitize any user provided or variable input. + + This plugin test is part of a family of tests built to check for process + spawning and warn appropriately. Specifically, this test looks for the + spawning of a subprocess using a command shell. This type of subprocess + invocation is dangerous as it is vulnerable to various shell injection + attacks. Great care should be taken to sanitize all input in order to + mitigate this risk. Calls of this type are identified by the use of certain + commands which are known to use shells. Bandit will report a MEDIUM + severity warning. + + See also: + + - :doc:`../plugins/linux_commands_wildcard_injection` + - :doc:`../plugins/subprocess_without_shell_equals_true` + - :doc:`../plugins/start_process_with_no_shell` + - :doc:`../plugins/start_process_with_partial_path` + - :doc:`../plugins/subprocess_popen_with_shell_equals_true` + + Config Options: + + This plugin test shares a configuration with others in the same family, + namely `shell_injection`. This configuration is divided up into three + sections, `subprocess`, `shell` and `no_shell`. They each list Python calls + that spawn subprocesses, invoke commands within a shell, or invoke commands + without a shell (by replacing the calling process) respectively. + + This plugin specifically scans for methods listed in `shell` section. + + .. code-block:: yaml + + 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 + + Sample Output: + + .. code-block:: none + + >> Issue: Starting a process with a shell: check for injection. + Severity: Medium Confidence: Medium + Location: examples/os_system.py:3 + 2 + 3 os.system('/bin/echo hi') + + References: + + - https://security.openstack.org + - https://docs.python.org/2/library/os.html#os.system + - https://docs.python.org/2/library/subprocess.html#frequently-used-arguments # noqa + - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html + + .. versionadded:: 0.10.0 + """ if config and context.call_function_name_qual in config['shell']: if len(context.call_args) > 0: sev = _evaluate_shell_call(context) @@ -144,6 +431,81 @@ def start_process_with_a_shell(context, config): @takes_config('shell_injection') @checks('Call') def start_process_with_no_shell(context, config): + """start_process_with_no_shell + + Python possesses many mechanisms to invoke an external executable. However, + doing so may present a security issue if appropriate care is not taken to + sanitize any user provided or variable input. + + This plugin test is part of a family of tests built to check for process + spawning and warn appropriately. Specifically, this test looks for the + spawning of a subprocess in a way that doesn't use a shell. Although this + is generally safe, it maybe useful for penetration testing workflows to + track where external system calls are used. As such a LOW severity message + is generated. + + See also: + + - :doc:`../plugins/linux_commands_wildcard_injection` + - :doc:`../plugins/subprocess_without_shell_equals_true` + - :doc:`../plugins/start_process_with_a_shell` + - :doc:`../plugins/start_process_with_partial_path` + - :doc:`../plugins/subprocess_popen_with_shell_equals_true` + + Config Options: + + This plugin test shares a configuration with others in the same family, + namely `shell_injection`. This configuration is divided up into three + sections, `subprocess`, `shell` and `no_shell`. They each list Python calls + that spawn subprocesses, invoke commands within a shell, or invoke commands + without a shell (by replacing the calling process) respectively. + + This plugin specifically scans for methods listed in `no_shell` section. + + .. code-block:: yaml + + 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 + + Sample Output: + + .. code-block:: none + + >> Issue: [start_process_with_no_shell] Starting a process without a + shell. + Severity: Low Confidence: Medium + Location: examples/os-spawn.py:8 + 7 os.spawnv(mode, path, args) + 8 os.spawnve(mode, path, args, env) + 9 os.spawnvp(mode, file, args) + + References: + + - https://security.openstack.org + - https://docs.python.org/2/library/os.html#os.system + - https://docs.python.org/2/library/subprocess.html#frequently-used-arguments # noqa + - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html + + .. versionadded:: 0.10.0 + """ + if config and context.call_function_name_qual in config['no_shell']: return bandit.Issue( severity=bandit.LOW, @@ -155,6 +517,78 @@ def start_process_with_no_shell(context, config): @takes_config('shell_injection') @checks('Call') def start_process_with_partial_path(context, config): + """start_process_with_partial_path + + Python possesses many mechanisms to invoke an external executable. If the + desired executable path is not fully qualified relative to the filesystem + root then this may present a potential security risk. + + In POSIX environments, the `PATH` environment variable is used to specify a + set of standard locations that will be searched for the first matching + named executable. While convenient, this behavior may allow a malicious + actor to exert control over a system. If they are able to adjust the + contents of the `PATH` variable, or manipulate the file system, then a + bogus executable may be discovered in place of the desired one. This + executable will be invoked with the user privileges of the Python process + that spawned it, potentially a highly privileged user. + + This test will scan the parameters of all configured Python methods, + looking for paths that do not start at the filesystem root, that is, do not + have a leading '/' character. + + Config Options: + + This plugin test shares a configuration with others in the same family, + namely `shell_injection`. This configuration is divided up into three + sections, `subprocess`, `shell` and `no_shell`. They each list Python calls + that spawn subprocesses, invoke commands within a shell, or invoke commands + without a shell (by replacing the calling process) respectively. + + This test will scan parameters of all methods in all sections. Note that + methods are fully qualified and de-aliased prior to checking. + + .. code-block:: yaml + + shell_injection: + # Start a process using the subprocess module, or one of its + wrappers. + subprocess: + - subprocess.Popen + - subprocess.call + + # Start a process with a function vulnerable to shell injection. + shell: + - os.system + - os.popen + - 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 + + + Sample Output: + + .. code-block:: none + + >> Issue: Starting a process with a partial executable path + Severity: Low Confidence: High + Location: ./examples/partial_path_process.py:3 + 2 from subprocess import Popen as pop + 3 pop('gcc --version', shell=False) + + References: + + - https://security.openstack.org + - https://docs.python.org/2/library/os.html#process-management + + .. versionadded:: 0.13.0 + """ + if config and len(context.call_args): if(context.call_function_name_qual in config['subprocess'] or context.call_function_name_qual in config['shell'] or diff --git a/bandit/plugins/injection_sql.py b/bandit/plugins/injection_sql.py index e3d1fc8d..be94cb80 100644 --- a/bandit/plugins/injection_sql.py +++ b/bandit/plugins/injection_sql.py @@ -14,6 +14,53 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +An SQL injection attack consists of insertion or "injection" of a SQL query via +the input data given to an application. It is a very common attack vector. This +plugin test looks for strings that resemble SQL statements that are involved in +some form of string building operation. For example: + + - "SELECT %s FROM derp;" % var + - "SELECT thing FROM " + tab + - "SELECT " + val + " FROM " + tab + ... + +Unless care is taken to sanitize and control the input data when building such +SQL statement strings, an injection attack becomes possible. If strings of this +nature are discovered, a LOW confidence issue is reported. In order to boost +result confidence, this plugin test will also check to see if the discovered +string is in use with standard Python DBAPI calls `execute` or `executemany`. +If so, a MEDIUM issue is reported. For example: + + - cursor.execute("SELECT %s FROM derp;" % var) + +Config Options +-------------- +None + + +Sample Output +------------- +.. code-block:: none + + >> Issue: Possible SQL injection vector through string-based query + construction. + Severity: Medium Confidence: Low + Location: ./examples/sql_statements_without_sql_alchemy.py:4 + 3 query = "DELETE FROM foo WHERE id = '%s'" % identifier + 4 query = "UPDATE foo SET value = 'b' WHERE id = '%s'" % identifier + 5 + +References +---------- +- https://www.owasp.org/index.php/SQL_Injection +- https://security.openstack.org/guidelines/dg_parameterize-database-queries.html # noqa + +.. versionadded:: 0.9.0 + +""" + import ast import bandit diff --git a/bandit/plugins/injection_wildcard.py b/bandit/plugins/injection_wildcard.py index 59a9ddde..7e65ddbb 100644 --- a/bandit/plugins/injection_wildcard.py +++ b/bandit/plugins/injection_wildcard.py @@ -14,6 +14,96 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Python provides a number of methods that emulate the behavior of standard Linux +command line utilities. Like their Linux counterparts, these commands may take +a wildcard "\*" character in place of a file system path. This is interpreted +to mean "any and all files or folders" and can be used to build partially +qualified paths, such as "/home/user/\*". + +The use of partially qualified paths may result in unintended consequences if +an unexpected file or symlink is placed into the path location given. This +becomes particularly dangerous when combined with commands used to manipulate +file permissions or copy data off of a system. + +This test plugin looks for usage of the following commands in conjunction with +wild card parameters: + +- 'chown' +- 'chmod' +- 'tar' +- 'rsync' + +As well as any method configured in the shell or subprocess injection test +configurations. + + +Config Options +-------------- +This plugin test shares a configuration with others in the same family, namely +`shell_injection`. This configuration is divided up into three sections, +`subprocess`, `shell` and `no_shell`. They each list Python calls that spawn +subprocesses, invoke commands within a shell, or invoke commands without a +shell (by replacing the calling process) respectively. + +This test will scan parameters of all methods in all sections. Note that +methods are fully qualified and de-aliased prior to checking. + + +.. code-block:: yaml + + shell_injection: + # Start a process using the subprocess module, or one of its wrappers. + subprocess: + - subprocess.Popen + - subprocess.call + + # Start a process with a function vulnerable to shell injection. + shell: + - os.system + - os.popen + - 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 + + +Sample Output +------------- +.. code-block:: none + + >> Issue: Possible wildcard injection in call: subprocess.Popen + Severity: High Confidence: Medium + Location: ./examples/wildcard-injection.py:8 + 7 o.popen2('/bin/chmod *') + 8 subp.Popen('/bin/chown *', shell=True) + 9 + + >> Issue: subprocess call - check for execution of untrusted input. + Severity: Low Confidence: High + Location: ./examples/wildcard-injection.py:11 + 10 # Not vulnerable to wildcard injection + 11 subp.Popen('/bin/rsync *') + 12 subp.Popen("/bin/chmod *") + + +References +---------- +- https://security.openstack.org +- https://en.wikipedia.org/wiki/Wildcard_character +- http://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt + +.. versionadded:: 0.9.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/bandit/plugins/insecure_ssl_tls.py b/bandit/plugins/insecure_ssl_tls.py index b23c90b7..4eff86bd 100644 --- a/bandit/plugins/insecure_ssl_tls.py +++ b/bandit/plugins/insecure_ssl_tls.py @@ -25,6 +25,83 @@ def get_bad_proto_versions(config): @takes_config @checks('Call') def ssl_with_bad_version(context, config): + """Test for SSL use with bad version used + + Several highly publicized exploitable flaws have been discovered + in all versions of SSL and early versions of TLS. It is strongly + recommended that use of the following known broken protocol versions be + avoided: + + - SSL v2 + - SSL v3 + - TLS v1 + - TLS v1.1 + + This plugin test scans for calls to Python methods with parameters that + indicate the used broken SSL/TLS protocol versions. Currently, detection + supports methods using Python's native SSL/TLS support and the pyOpenSSL + module. A HIGH severity warning will be reported whenever known broken + protocol versions are detected. + + It is worth noting that native support for TLS 1.2 is only available in + more recent Python versions, specifically 2.7.9 and up, and 3.x + + See also: + + - :doc:`../plugins/ssl_with_bad_defaults` + - :doc:`../plugins/ssl_with_no_version` + + A note on 'SSLv23': + + Amongst the available SSL/TLS versions provided by Python/pyOpenSSL there + exists the option to use SSLv23. This very poorly named option actually + means "use the highest version of SSL/TLS supported by both the server and + client". This may (and should be) a version well in advance of SSL v2 or + v3. Bandit can scan for the use of SSLv23 if desired, but its detection + does not necessarily indicate a problem. + + When using SSLv23 it is important to also provide flags to explicitly + exclude bad versions of SSL/TLS from the protocol versions considered. Both + the Python native and pyOpenSSL modules provide the ``OP_NO_SSLv2`` and + ``OP_NO_SSLv3`` flags for this purpose. + + + Config Options: + + .. code-block:: yaml + + 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 + + + Sample Output: + + .. code-block:: none + + >> Issue: ssl.wrap_socket call with insecure SSL/TLS protocol version + identified, security issue. + Severity: High Confidence: High + Location: ./examples/ssl-insecure-version.py:13 + 12 # strict tests + 13 ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv3) + 14 ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1) + + References: + + - http://heartbleed.com/ + - https://poodlebleed.com/ + - https://security.openstack.org/ + - https://security.openstack.org/guidelines/dg_move-data-securely.html + + .. versionadded:: 0.9.0 + """ bad_ssl_versions = get_bad_proto_versions(config) if (context.call_function_name_qual == 'ssl.wrap_socket'): if context.check_call_arg_value('ssl_version', bad_ssl_versions): @@ -58,6 +135,51 @@ def ssl_with_bad_version(context, config): @takes_config("ssl_with_bad_version") @checks('FunctionDef') def ssl_with_bad_defaults(context, config): + """Test for SSL use with bad defaults specified + + This plugin is part of a family of tests that detect the use of known bad + versions of SSL/TLS, please see :doc:`../plugins/ssl_with_bad_version` for + a complete discussion. Specifically, this plugin test scans for Python + methods with default parameter values that specify the use of broken + SSL/TLS protocol versions. Currently, detection supports methods using + Python's native SSL/TLS support and the pyOpenSSL module. A MEDIUM severity + warning will be reported whenever known broken protocol versions are + detected. + + See also: + + - :doc:`../plugins/ssl_with_bad_version` + - :doc:`../plugins/ssl_with_no_version` + + + Config Options: + + This test shares the configuration provided for the standard + :doc:`../plugins/ssl_with_bad_version` test, please refer to its + documentation. + + Sample Output: + + .. code-block:: none + + >> Issue: Function definition identified with insecure SSL/TLS protocol + version by default, possible security issue. + Severity: Medium Confidence: Medium + Location: ./examples/ssl-insecure-version.py:28 + 27 + 28 def open_ssl_socket(version=SSL.SSLv2_METHOD): + 29 pass + + References: + + - http://heartbleed.com/ + - https://poodlebleed.com/ + - https://security.openstack.org/ + - https://security.openstack.org/guidelines/dg_move-data-securely.html + + .. versionadded:: 0.9.0 + """ + bad_ssl_versions = get_bad_proto_versions(config) for default in context.function_def_defaults_qual: val = default.split(".")[-1] @@ -73,6 +195,51 @@ def ssl_with_bad_defaults(context, config): @checks('Call') def ssl_with_no_version(context): + """Test for SSL use with no version specified + + This plugin is part of a family of tests that detect the use of known bad + versions of SSL/TLS, please see :doc:`../plugins/ssl_with_bad_version` for + a complete discussion. Specifically, This plugin test scans for specific + methods in Python's native SSL/TLS support and the pyOpenSSL module that + configure the version of SSL/TLS protocol to use. These methods are known + to provide default value that maximize compatibility, but permit use of the + aforementioned broken protocol versions. A LOW severity warning will be + reported whenever this is detected. + + See also: + + - :doc:`../plugins/ssl_with_bad_version` + - :doc:`../plugins/ssl_with_bad_defaults` + + + Config Options: + + This test shares the configuration provided for the standard + :doc:`../plugins/ssl_with_bad_version` test, please refer to its + documentation. + + Sample Output: + + .. code-block:: none + + >> Issue: ssl.wrap_socket call with no SSL/TLS protocol version + specified, the default SSLv23 could be insecure, possible security + issue. + Severity: Low Confidence: Medium + Location: ./examples/ssl-insecure-version.py:23 + 22 + 23 ssl.wrap_socket() + 24 + + References: + + - http://heartbleed.com/ + - https://poodlebleed.com/ + - https://security.openstack.org/ + - https://security.openstack.org/guidelines/dg_move-data-securely.html + + .. versionadded:: 0.9.0 + """ if (context.call_function_name_qual == 'ssl.wrap_socket'): if context.check_call_arg_value('ssl_version') is None: # check_call_arg_value() returns False if the argument is found diff --git a/bandit/plugins/jinja2_templates.py b/bandit/plugins/jinja2_templates.py index 1e606f63..3e957d11 100644 --- a/bandit/plugins/jinja2_templates.py +++ b/bandit/plugins/jinja2_templates.py @@ -14,6 +14,64 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Jinja2 is a Python HTML templating system. It is typically used to build web +applications, though appears in other places well, notably the Ansible +automation system. When configuring the Jinja2 environment, the option to use +autoescaping on input can be specified. When autoescaping is enabled, Jinja2 +will filter input strings to escape any HTML content submitted via template +variables. Without escaping HTML input the application becomes vulnerable to +Cross Site Scripting (XSS) attacks. + +Unfortunately, autoescaping is False by default. Thus this plugin test will +warn on omission of an autoescape setting, as well as an explicit setting of +false. A HIGH severity warning is generated in either of these scenarios. + +Config Options +-------------- +None + + +Sample Output +------------- + +.. code-block:: none + + >> Issue: Using jinja2 templates with autoescape=False is dangerous and can + lead to XSS. Use autoescape=True to mitigate XSS vulnerabilities. + Severity: High Confidence: High + Location: ./examples/jinja2_templating.py:11 + 10 templateEnv = jinja2.Environment(autoescape=False, + loader=templateLoader) + 11 Environment(loader=templateLoader, + 12 load=templateLoader, + 13 autoescape=False) + 14 + + >> Issue: By default, jinja2 sets autoescape to False. Consider using + autoescape=True to mitigate XSS vulnerabilities. + Severity: High Confidence: High + Location: ./examples/jinja2_templating.py:15 + 14 + 15 Environment(loader=templateLoader, + 16 load=templateLoader) + 17 + + +References +---------- +- https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) +- https://realpython.com/blog/python/primer-on-jinja-templating/ +- http://jinja.pocoo.org/docs/dev/api/#autoescaping +- https://security.openstack.org +- https://security.openstack.org/guidelines/dg_cross-site-scripting-xss.html + +.. versionadded:: 0.10.0 + +""" + import ast import bandit diff --git a/bandit/plugins/mako_templates.py b/bandit/plugins/mako_templates.py index f6816774..00f1ab07 100644 --- a/bandit/plugins/mako_templates.py +++ b/bandit/plugins/mako_templates.py @@ -12,6 +12,47 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Mako is a Python templating system often used to build web applications. It is +the default templating system used in Pylons and Pyramid. Unlike Jinja2 (an +alternative templating system), Mako has no environment wide variable escaping +mechanism. Because of this, all input variables must be carefully escaped +before use to prevent possible vulnerabilities to Cross Site Scripting (XSS) +attacks. + + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: Mako templates allow HTML/JS rendering by default and are + inherently open to XSS attacks. Ensure variables in all templates are + properly sanitized via the 'n', 'h' or 'x' flags (depending on context). + For example, to HTML escape the variable 'data' do ${ data |h }. + Severity: Medium Confidence: High + Location: ./examples/mako_templating.py:10 + 9 + 10 mako.template.Template("hern") + 11 template.Template("hern") + + +References +---------- +- http://www.makotemplates.org/ +- https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) +- https://security.openstack.org +- https://security.openstack.org/guidelines/dg_cross-site-scripting-xss.html + +.. versionadded:: 0.10.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/bandit/plugins/secret_config_option.py b/bandit/plugins/secret_config_option.py index 9ff6c395..798c4836 100644 --- a/bandit/plugins/secret_config_option.py +++ b/bandit/plugins/secret_config_option.py @@ -12,6 +12,60 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Passwords are sensitive and must be protected appropriately. In OpenStack +Oslo there is an option to mark options "secret" which will ensure that they +are not logged. This plugin detects usages of oslo configuration functions +that appear to deal with strings ending in 'password' and flag usages where +they have not been marked secret. + +If such a value is found a MEDIUM severity error is generated. If 'False' or +'None' are explicitly set, Bandit will return a MEDIUM confidence issue. If +Bandit can't determine the value of secret it will return a LOW confidence +issue. + +Config Options +-------------- +.. code-block:: yaml + + password_config_option_not_marked_secret: + function_names: + - oslo.config.cfg.StrOpt + - oslo_config.cfg.StrOpt + +Sample Output +------------- +.. code-block:: none + + >> Issue: [password_config_option_not_marked_secret] oslo config option + possibly not marked secret=True identified. + Severity: Medium Confidence: Low + Location: examples/secret-config-option.py:12 + 11 help="User's password"), + 12 cfg.StrOpt('nova_password', + 13 secret=secret, + 14 help="Nova user password"), + 15 ] + + >> Issue: [password_config_option_not_marked_secret] oslo config option not + marked secret=True identifed, security issue. + Severity: Medium Confidence: Medium + Location: examples/secret-config-option.py:21 + 20 help="LDAP ubind ser name"), + 21 cfg.StrOpt('ldap_password', + 22 help="LDAP bind user password"), + 23 cfg.StrOpt('ldap_password_attribute', + +References +---------- +- https://security.openstack.org/guidelines/dg_protect-sensitive-data-in-files.html # noqa + +.. versionadded:: 0.10.0 + +""" + import bandit from bandit.core.test_properties import * from bandit.core import constants diff --git a/bandit/plugins/try_except_pass.py b/bandit/plugins/try_except_pass.py index 614cff36..a08bbb41 100644 --- a/bandit/plugins/try_except_pass.py +++ b/bandit/plugins/try_except_pass.py @@ -14,6 +14,70 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +Errors in Python code bases are typically communicated using ``Exceptions``. +An exception object is 'raised' in the event of an error and can be 'caught' at +a later point in the program, typically some error handling or logging action +will then be performed. + +However, it is possible to catch an exception and silently ignore it. This is +illustrated with the following example + +.. code-block:: python + + try: + do_some_stuff() + except Exception: + pass + +This pattern is considered bad practice in general, but also represents a +potential security issue. A larger than normal volume of errors from a service +can indicate an attempt is being made to disrupt or interfere with it. Thus +errors should, at the very least, be logged. + +There are rare situations where it is desirable to suppress errors, but this is +typically done with specific exception types, rather than the base Exception +class (or no type). To accommodate this, the test may be configured to ignore +'try, except, pass' where the exception is typed. For example, the following +would not generate a warning if the configuration option +``checked_typed_exception`` is set to False: + +.. code-block:: python + + try: + do_some_stuff() + except ZeroDivisionError: + pass + +Config Options +-------------- +.. code-block:: yaml + + try_except_pass: + check_typed_exception: True + + +Sample Output +------------- +.. code-block:: none + + >> Issue: Try, Except, Pass detected. + Severity: Low Confidence: High + Location: ./examples/try_except_pass.py:4 + 3 a = 1 + 4 except: + 5 pass + +References +---------- +- https://security.openstack.org + +.. versionadded:: 0.13.0 + +""" + import ast import bandit diff --git a/bandit/plugins/weak_cryptographic_key.py b/bandit/plugins/weak_cryptographic_key.py index fbf2e2c2..2e82d835 100644 --- a/bandit/plugins/weak_cryptographic_key.py +++ b/bandit/plugins/weak_cryptographic_key.py @@ -12,6 +12,40 @@ # License for the specific language governing permissions and limitations # under the License. +r""" +Description +----------- +As computational power increases, so does the ability to break ciphers with +smaller key lengths. The recommended key length size is 2048 and higher. 1024 +bits and below are now considered breakable. This plugin test checks for use +of any key less than 2048 bits and returns a high severity error if lower than +1024 and a medium severity error greater than 1024 but less than 2048. + +Config Options +-------------- +None + +Sample Output +------------- +.. code-block:: none + + >> Issue: DSA key sizes below 1024 bits are considered breakable. + Severity: High Confidence: High + Location: examples/weak_cryptographic_key_sizes.py:36 + 35 # Also incorrect: without keyword args + 36 dsa.generate_private_key(512, + 37 backends.default_backend()) + 38 rsa.generate_private_key(3, + +References +---------- + - http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf + - https://security.openstack.org/guidelines/dg_strong-crypto.html + +.. versionadded:: 0.14.0 + +""" + import bandit from bandit.core.test_properties import * diff --git a/docs/old/exec.md b/doc/old/exec.md similarity index 100% rename from docs/old/exec.md rename to doc/old/exec.md diff --git a/docs/old/jinja2.md b/doc/old/jinja2.md similarity index 100% rename from docs/old/jinja2.md rename to doc/old/jinja2.md diff --git a/docs/old/partial_paths.md b/doc/old/partial_paths.md similarity index 100% rename from docs/old/partial_paths.md rename to doc/old/partial_paths.md diff --git a/docs/old/ssl_tls.md b/doc/old/ssl_tls.md similarity index 100% rename from docs/old/ssl_tls.md rename to doc/old/ssl_tls.md diff --git a/docs/old/temp.md b/doc/old/temp.md similarity index 100% rename from docs/old/temp.md rename to doc/old/temp.md diff --git a/docs/old/xml.md b/doc/old/xml.md similarity index 100% rename from docs/old/xml.md rename to doc/old/xml.md diff --git a/docs/old/yaml.md b/doc/old/yaml.md similarity index 100% rename from docs/old/yaml.md rename to doc/old/yaml.md diff --git a/docs/source/conf.py b/doc/source/conf.py similarity index 100% rename from docs/source/conf.py rename to doc/source/conf.py diff --git a/docs/source/config.rst b/doc/source/config.rst similarity index 100% rename from docs/source/config.rst rename to doc/source/config.rst diff --git a/docs/source/formatters/index.rst b/doc/source/formatters/index.rst similarity index 100% rename from docs/source/formatters/index.rst rename to doc/source/formatters/index.rst diff --git a/docs/source/index.rst b/doc/source/index.rst similarity index 97% rename from docs/source/index.rst rename to doc/source/index.rst index 54301695..e1b3f86a 100644 --- a/docs/source/index.rst +++ b/doc/source/index.rst @@ -15,7 +15,7 @@ Getting Started :maxdepth: 1 config - tests/index + plugins/index formatters/index Indices and tables diff --git a/doc/source/plugins/any_other_function_with_shell_equals_true.rst b/doc/source/plugins/any_other_function_with_shell_equals_true.rst new file mode 100644 index 00000000..a4bcab3a --- /dev/null +++ b/doc/source/plugins/any_other_function_with_shell_equals_true.rst @@ -0,0 +1,8 @@ +----------------------------------------- +any_other_function_with_shell_equals_true +----------------------------------------- + +.. currentmodule:: bandit.plugins.injection_shell + +.. autofunction:: any_other_function_with_shell_equals_true + :noindex: diff --git a/doc/source/plugins/assert_used.rst b/doc/source/plugins/assert_used.rst new file mode 100644 index 00000000..5167d2fe --- /dev/null +++ b/doc/source/plugins/assert_used.rst @@ -0,0 +1,5 @@ +----------- +assert_used +----------- + +.. automodule:: bandit.plugins.asserts diff --git a/doc/source/plugins/blacklist_calls.rst b/doc/source/plugins/blacklist_calls.rst new file mode 100644 index 00000000..4c69869f --- /dev/null +++ b/doc/source/plugins/blacklist_calls.rst @@ -0,0 +1,5 @@ +--------------- +blacklist_calls +--------------- + +.. automodule:: bandit.plugins.blacklist_calls diff --git a/doc/source/plugins/blacklist_import_func.rst b/doc/source/plugins/blacklist_import_func.rst new file mode 100644 index 00000000..6efe10c0 --- /dev/null +++ b/doc/source/plugins/blacklist_import_func.rst @@ -0,0 +1,8 @@ +--------------------- +blacklist_import_func +--------------------- + +.. currentmodule:: bandit.plugins.blacklist_imports + +.. autofunction:: blacklist_import_func + :noindex: diff --git a/doc/source/plugins/blacklist_imports.rst b/doc/source/plugins/blacklist_imports.rst new file mode 100644 index 00000000..ea821201 --- /dev/null +++ b/doc/source/plugins/blacklist_imports.rst @@ -0,0 +1,8 @@ +----------------- +blacklist_imports +----------------- + +.. currentmodule:: bandit.plugins.blacklist_imports + +.. autofunction:: blacklist_imports + :noindex: diff --git a/doc/source/plugins/exec_used.rst b/doc/source/plugins/exec_used.rst new file mode 100644 index 00000000..31994a5a --- /dev/null +++ b/doc/source/plugins/exec_used.rst @@ -0,0 +1,5 @@ +--------- +exec_used +--------- + +.. automodule:: bandit.plugins.exec diff --git a/doc/source/plugins/execute_with_run_as_root_equals_true.rst b/doc/source/plugins/execute_with_run_as_root_equals_true.rst new file mode 100644 index 00000000..a2198899 --- /dev/null +++ b/doc/source/plugins/execute_with_run_as_root_equals_true.rst @@ -0,0 +1,5 @@ +------------------------------------ +execute_with_run_as_root_equals_true +------------------------------------ + +.. automodule:: bandit.plugins.exec_as_root diff --git a/doc/source/plugins/flask_debug_true.rst b/doc/source/plugins/flask_debug_true.rst new file mode 100644 index 00000000..06f472ad --- /dev/null +++ b/doc/source/plugins/flask_debug_true.rst @@ -0,0 +1,5 @@ +---------------- +flask_debug_true +---------------- + +.. automodule:: bandit.plugins.app_debug diff --git a/doc/source/plugins/hardcoded_bind_all_interfaces.rst b/doc/source/plugins/hardcoded_bind_all_interfaces.rst new file mode 100644 index 00000000..6011ea05 --- /dev/null +++ b/doc/source/plugins/hardcoded_bind_all_interfaces.rst @@ -0,0 +1,5 @@ +----------------------------- +hardcoded_bind_all_interfaces +----------------------------- + +.. automodule:: bandit.plugins.general_bind_all_interfaces diff --git a/doc/source/plugins/hardcoded_password.rst b/doc/source/plugins/hardcoded_password.rst new file mode 100644 index 00000000..b0259e75 --- /dev/null +++ b/doc/source/plugins/hardcoded_password.rst @@ -0,0 +1,5 @@ +------------------- +hardcoded_passwords +------------------- + +.. automodule:: bandit.plugins.general_hardcoded_password diff --git a/doc/source/plugins/hardcoded_sql_expressions.rst b/doc/source/plugins/hardcoded_sql_expressions.rst new file mode 100644 index 00000000..4196d644 --- /dev/null +++ b/doc/source/plugins/hardcoded_sql_expressions.rst @@ -0,0 +1,5 @@ +------------------------- +hardcoded_sql_expressions +------------------------- + +.. automodule:: bandit.plugins.injection_sql diff --git a/doc/source/plugins/hardcoded_tmp_directory.rst b/doc/source/plugins/hardcoded_tmp_directory.rst new file mode 100644 index 00000000..912eff51 --- /dev/null +++ b/doc/source/plugins/hardcoded_tmp_directory.rst @@ -0,0 +1,5 @@ +----------------------- +hardcoded_tmp_directory +----------------------- + +.. automodule:: bandit.plugins.general_hardcoded_tmp diff --git a/docs/source/tests/index.rst b/doc/source/plugins/index.rst similarity index 100% rename from docs/source/tests/index.rst rename to doc/source/plugins/index.rst diff --git a/doc/source/plugins/jinja2_autoescape_false.rst b/doc/source/plugins/jinja2_autoescape_false.rst new file mode 100644 index 00000000..1d77792f --- /dev/null +++ b/doc/source/plugins/jinja2_autoescape_false.rst @@ -0,0 +1,5 @@ +----------------------- +jinja2_autoescape_false +----------------------- + +.. automodule:: bandit.plugins.jinja2_templates diff --git a/doc/source/plugins/linux_commands_wildcard_injection.rst b/doc/source/plugins/linux_commands_wildcard_injection.rst new file mode 100644 index 00000000..5f65b1ef --- /dev/null +++ b/doc/source/plugins/linux_commands_wildcard_injection.rst @@ -0,0 +1,5 @@ +--------------------------------- +linux_commands_wildcard_injection +--------------------------------- + +.. automodule:: bandit.plugins.injection_wildcard diff --git a/doc/source/plugins/paramiko_calls.rst b/doc/source/plugins/paramiko_calls.rst new file mode 100644 index 00000000..e603889e --- /dev/null +++ b/doc/source/plugins/paramiko_calls.rst @@ -0,0 +1,5 @@ +-------------- +paramiko_calls +-------------- + +.. automodule:: bandit.plugins.injection_paramiko diff --git a/doc/source/plugins/password_config_option_not_marked_secret.rst b/doc/source/plugins/password_config_option_not_marked_secret.rst new file mode 100644 index 00000000..3c63c530 --- /dev/null +++ b/doc/source/plugins/password_config_option_not_marked_secret.rst @@ -0,0 +1,5 @@ +---------------------------------------- +password_config_option_not_marked_secret +---------------------------------------- + +.. automodule:: bandit.plugins.secret_config_option diff --git a/doc/source/plugins/request_with_no_cert_validation.rst b/doc/source/plugins/request_with_no_cert_validation.rst new file mode 100644 index 00000000..db84cefb --- /dev/null +++ b/doc/source/plugins/request_with_no_cert_validation.rst @@ -0,0 +1,5 @@ +------------------------------- +request_with_no_cert_validation +------------------------------- + +.. automodule:: bandit.plugins.crypto_request_no_cert_validation diff --git a/doc/source/plugins/set_bad_file_permissions.rst b/doc/source/plugins/set_bad_file_permissions.rst new file mode 100644 index 00000000..80212616 --- /dev/null +++ b/doc/source/plugins/set_bad_file_permissions.rst @@ -0,0 +1,5 @@ +------------------------ +set_bad_file_permissions +------------------------ + +.. automodule:: bandit.plugins.general_bad_file_permissions diff --git a/doc/source/plugins/ssl_with_bad_defaults.rst b/doc/source/plugins/ssl_with_bad_defaults.rst new file mode 100644 index 00000000..c188e11e --- /dev/null +++ b/doc/source/plugins/ssl_with_bad_defaults.rst @@ -0,0 +1,8 @@ +--------------------- +ssl_with_bad_defaults +--------------------- + +.. currentmodule:: bandit.plugins.insecure_ssl_tls + +.. autofunction:: ssl_with_bad_version + :noindex: diff --git a/doc/source/plugins/ssl_with_bad_version.rst b/doc/source/plugins/ssl_with_bad_version.rst new file mode 100644 index 00000000..0efe6669 --- /dev/null +++ b/doc/source/plugins/ssl_with_bad_version.rst @@ -0,0 +1,8 @@ +-------------------- +ssl_with_bad_version +-------------------- + +.. currentmodule:: bandit.plugins.insecure_ssl_tls + +.. autofunction:: ssl_with_bad_defaults + :noindex: diff --git a/doc/source/plugins/ssl_with_no_version.rst b/doc/source/plugins/ssl_with_no_version.rst new file mode 100644 index 00000000..a4ebbc58 --- /dev/null +++ b/doc/source/plugins/ssl_with_no_version.rst @@ -0,0 +1,8 @@ +------------------- +ssl_with_no_version +------------------- + +.. currentmodule:: bandit.plugins.insecure_ssl_tls + +.. autofunction:: ssl_with_no_version + :noindex: diff --git a/doc/source/plugins/start_process_with_a_shell.rst b/doc/source/plugins/start_process_with_a_shell.rst new file mode 100644 index 00000000..cfbe11c0 --- /dev/null +++ b/doc/source/plugins/start_process_with_a_shell.rst @@ -0,0 +1,8 @@ +-------------------------- +start_process_with_a_shell +-------------------------- + +.. currentmodule:: bandit.plugins.injection_shell + +.. autofunction:: start_process_with_a_shell + :noindex: diff --git a/doc/source/plugins/start_process_with_no_shell.rst b/doc/source/plugins/start_process_with_no_shell.rst new file mode 100644 index 00000000..86d41a08 --- /dev/null +++ b/doc/source/plugins/start_process_with_no_shell.rst @@ -0,0 +1,8 @@ +--------------------------- +start_process_with_no_shell +--------------------------- + +.. currentmodule:: bandit.plugins.injection_shell + +.. autofunction:: start_process_with_no_shell + :noindex: diff --git a/doc/source/plugins/start_process_with_partial_path.rst b/doc/source/plugins/start_process_with_partial_path.rst new file mode 100644 index 00000000..41ec62be --- /dev/null +++ b/doc/source/plugins/start_process_with_partial_path.rst @@ -0,0 +1,8 @@ +------------------------------- +start_process_with_partial_path +------------------------------- + +.. currentmodule:: bandit.plugins.injection_shell + +.. autofunction:: start_process_with_partial_path + :noindex: diff --git a/doc/source/plugins/subprocess_popen_with_shell_equals_true.rst b/doc/source/plugins/subprocess_popen_with_shell_equals_true.rst new file mode 100644 index 00000000..13d2c799 --- /dev/null +++ b/doc/source/plugins/subprocess_popen_with_shell_equals_true.rst @@ -0,0 +1,8 @@ +--------------------------------------- +subprocess_popen_with_shell_equals_true +--------------------------------------- + +.. currentmodule:: bandit.plugins.injection_shell + +.. autofunction:: subprocess_popen_with_shell_equals_true + :noindex: diff --git a/doc/source/plugins/subprocess_without_shell_equals_true.rst b/doc/source/plugins/subprocess_without_shell_equals_true.rst new file mode 100644 index 00000000..2dfc8046 --- /dev/null +++ b/doc/source/plugins/subprocess_without_shell_equals_true.rst @@ -0,0 +1,8 @@ +------------------------------------ +subprocess_without_shell_equals_true +------------------------------------ + +.. currentmodule:: bandit.plugins.injection_shell + +.. autofunction:: subprocess_without_shell_equals_true + :noindex: diff --git a/doc/source/plugins/try_except_pass.rst b/doc/source/plugins/try_except_pass.rst new file mode 100644 index 00000000..a895bab6 --- /dev/null +++ b/doc/source/plugins/try_except_pass.rst @@ -0,0 +1,5 @@ +--------------- +try_except_pass +--------------- + +.. automodule:: bandit.plugins.try_except_pass diff --git a/doc/source/plugins/use_of_mako_templates.rst b/doc/source/plugins/use_of_mako_templates.rst new file mode 100644 index 00000000..33641549 --- /dev/null +++ b/doc/source/plugins/use_of_mako_templates.rst @@ -0,0 +1,5 @@ +--------------------- +use_of_mako_templates +--------------------- + +.. automodule:: bandit.plugins.mako_templates diff --git a/doc/source/plugins/weak_cryptographic_key.rst b/doc/source/plugins/weak_cryptographic_key.rst new file mode 100644 index 00000000..44482967 --- /dev/null +++ b/doc/source/plugins/weak_cryptographic_key.rst @@ -0,0 +1,5 @@ +---------------------- +weak_cryptographic_key +---------------------- + +.. automodule:: bandit.plugins.weak_cryptographic_key diff --git a/docs/source/tests/any_other_function_with_shell_equals_true.rst b/docs/source/tests/any_other_function_with_shell_equals_true.rst deleted file mode 100644 index 90bddc93..00000000 --- a/docs/source/tests/any_other_function_with_shell_equals_true.rst +++ /dev/null @@ -1,65 +0,0 @@ -any_other_function_with_shell_equals_true -========================================= - -Description ------------ -Python possesses many mechanisms to invoke an external executable. However, -doing so may present a security issue if appropriate care is not taken to -sanitize any user provided or variable input. - -This plugin test is part of a family of tests built to check for process -spawning and warn appropriately. Specifically, this plugin test interrogates -method calls for the presence of a keyword parameter `shell` equalling true. It -is related to detection of shell injection issues and is intended to catch -custom wrappers to vulnerable methods that may have been created. - -See also: - -- :doc:`linux_commands_wildcard_injection`. -- :doc:`subprocess_popen_with_shell_equals_true`. -- :doc:`subprocess_without_shell_equals_true`. -- :doc:`start_process_with_no_shell`. -- :doc:`start_process_with_a_shell`. -- :doc:`start_process_with_partial_path`. - -Available Since ---------------- - - Bandit v 0.9.0 - -Config Options --------------- -This plugin test shares a configuration with others in the same family, namely -`shell_injection`. This configuration is divided up into three sections, -`subprocess`, `shell` and `no_shell`. They each list Python calls that spawn -subprocesses, invoke commands within a shell, or invoke commands without a -shell (by replacing the calling process) respectively. - -Specifically, this plugin excludes those functions listed under the subprocess -section, these methods are tested in a separate specific test plugin and this -exclusion prevents duplicate issue reporting. - -.. code-block:: yaml - - 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] - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Function call with shell=True parameter identified, possible - security issue. - Severity: Medium Confidence: High - Location: ./examples/subprocess_shell.py:9 - 8 pop('/bin/gcc --version', shell=True) - 9 Popen('/bin/gcc --version', shell=True) - 10 - -References ----------- - - https://security.openstack.org/guidelines/dg_avoid-shell-true.html - - https://security.openstack.org/guidelines/dg_use-subprocess-securely.html diff --git a/docs/source/tests/assert_used.rst b/docs/source/tests/assert_used.rst deleted file mode 100644 index 08faf7b0..00000000 --- a/docs/source/tests/assert_used.rst +++ /dev/null @@ -1,38 +0,0 @@ -assert_used -=========== - -Description ------------ -This plugin test checks for the use of the Python ``assert`` keyword. It was -discovered that some projects used assert to enforce interface constraints. -However, assert is removed with compiling to optimised byte code (python -o -producing \*.pyo files). This caused various protections to be removed. The use -of assert is also considered as general bad practice in OpenStack codebases. - -Please see https://docs.python.org/2/reference/simple_stmts.html#grammar-token-assert_stmt -for more info on ``assert`` - - -Available Since ---------------- - - Bandit v0.11.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: Use of assert detected. The enclosed code will be removed when compiling to optimised byte code. - Severity: Low Confidence: High - Location: ./examples/assert.py:1 - 1 assert logged_in - 2 display_assets() - -References ----------- - - https://bugs.launchpad.net/juniperopenstack/+bug/1456193 - - https://bugs.launchpad.net/heat/+bug/1397883 - - https://docs.python.org/2/reference/simple_stmts.html#grammar-token-assert_stmt diff --git a/docs/source/tests/blacklist_calls.rst b/docs/source/tests/blacklist_calls.rst deleted file mode 100644 index 96db71c9..00000000 --- a/docs/source/tests/blacklist_calls.rst +++ /dev/null @@ -1,71 +0,0 @@ - -blacklist_calls -=============== - -Description ------------ -A number of Python methods and functions are known to have potential security -implications. The blacklist calls plugin test is designed to detect the use of -these methods by scanning code for method calls and checking for their presence -in a configurable blacklist. The scanned calls are fully qualified and -de-aliased prior to checking. To illustrate this, imagine a check for -"evil.thing()" running on the following example code: - -.. code-block:: python - - import evil as good - - good.thing() - thing() - -This would generate a warning about calling `evil.thing()` despite the module -being aliased as `good`. It would also not generate a warning on the call to -`thing()` in the local module, as it's fully qualified name will not match. - -Each of the provided blacklisted calls can be grouped such that they generate -appropriate warnings (message, severity) and a token `{func}` may be used -in the provided output message, to be replaced with the actual method name. - -Due to the nature of the test, confidence is always reported as HIGH - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -.. code-block:: yaml - - 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 {func} is possibly dangerous. - level: LOW - -Sample Output -------------- -.. code-block:: none - - >> Issue: Pickle library appears to be in use, possible security issue. - - Severity: Medium Confidence: High - Location: ./examples/pickle_deserialize.py:20 - 19 serialized = cPickle.dumps({(): []}) - 20 print(cPickle.loads(serialized)) - 21 - -References ----------- -- https://security.openstack.org diff --git a/docs/source/tests/blacklist_import_func.rst b/docs/source/tests/blacklist_import_func.rst deleted file mode 100644 index 8c141fd7..00000000 --- a/docs/source/tests/blacklist_import_func.rst +++ /dev/null @@ -1,55 +0,0 @@ - -blacklist_import_func -===================== -Description ------------ -This test is in all ways identical to :doc:`blacklist_imports`. However, it -is designed to catch modules that have been imported using Python's special -builtin import function, `__import__()`. For example, running a test on the -following code for `module.evil` would warn as shown: - -.. code-block:: python - - __import__('module') # no warning - __import__('module.evil') # warning - -Please see the documentation for :doc:`blacklist_imports` for more details. - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -This test shares the configuration provided for the standard -:doc:`blacklist_imports` test. - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Using xml.sax to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace xml.sax with the equivalent defusedxml - package. - - Severity: Low Confidence: High - Location: ./examples/xml_sax.py:1 - 1 import xml.sax - 2 from xml import sax - - >> Issue: Using xml.sax.parseString to parse untrusted XML data is known to - be vulnerable to XML attacks. Replace xml.sax.parseString with its - defusedxml equivalent function. - - Severity: Medium Confidence: High - Location: ./examples/xml_sax.py:21 - 20 # bad - 21 xml.sax.parseString(xmlString, ExampleContentHandler()) - 22 xml.sax.parse('notaxmlfilethatexists.xml', ExampleContentHandler()) - - -References ----------- -- :doc:`blacklist_imports`. -- https://security.openstack.org diff --git a/docs/source/tests/blacklist_imports.rst b/docs/source/tests/blacklist_imports.rst deleted file mode 100644 index 3d7fa270..00000000 --- a/docs/source/tests/blacklist_imports.rst +++ /dev/null @@ -1,87 +0,0 @@ - -blacklist_imports -================= - -Description ------------ -A number of Python modules are known to provide collections of functionality -with potential security implications. The blacklist imports plugin test is -designed to detect the use of these modules by scanning code for `import` -statements and checking for the imported modules presence in a configurable -blacklist. The imported modules are fully qualified and de-aliased prior to -checking. To illustrate this, imagine a check for "module.evil" running on the -following example code: - -.. code-block:: python - - import module # no warning - import module.evil # warning - from module import evil # warning - from module import evil as good # warning - -This would generate a warning about importing `module.evil` in each of the last -three cases, despite the module being aliased as `good` in one of them. It would -also not generate a warning on the first import (of `module`) as it's fully -qualified name will not match. - -Each of the provided blacklisted modules can be grouped such that they generate -appropriate warnings (message, severity) and a token `{module}` may be used -in the provided output message, to be replaced with the actual module name. - -Due to the nature of the test, confidence is always reported as HIGH - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -.. code-block:: yaml - - blacklist_imports: - bad_import_sets: - - 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 - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Using xml.sax to parse untrusted XML data is known to be - vulnerable to XML attacks. Replace xml.sax with the equivalent defusedxml - package. - - Severity: Low Confidence: High - Location: ./examples/xml_sax.py:1 - 1 import xml.sax - 2 from xml import sax - - >> Issue: Using xml.sax.parseString to parse untrusted XML data is known to - be vulnerable to XML attacks. Replace xml.sax.parseString with its - defusedxml equivalent function. - - Severity: Medium Confidence: High - Location: ./examples/xml_sax.py:21 - 20 # bad - 21 xml.sax.parseString(xmlString, ExampleContentHandler()) - 22 xml.sax.parse('notaxmlfilethatexists.xml', ExampleContentHandler()) - -References ----------- -- see also :doc:`blacklist_import_func`. -- https://security.openstack.org diff --git a/docs/source/tests/exec_used.rst b/docs/source/tests/exec_used.rst deleted file mode 100644 index 10d8bcbe..00000000 --- a/docs/source/tests/exec_used.rst +++ /dev/null @@ -1,32 +0,0 @@ -exec_used -========= - -Description ------------ -This plugin test checks for the use of Python's `exec` method or keyword. The -Python docs succinctly describe why the use of `exec` is risky: - - - `This statement supports dynamic execution of Python code.` [1]_ - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: Use of exec detected. - Severity: Medium Confidence: High - Location: ./examples/exec-py2.py:2 - 1 exec("do evil") - 2 exec "do evil" - -References ----------- -.. [1] https://docs.python.org/2.0/ref/exec.html -.. [2] TODO : add info on exec and similar to sec best practice and link here diff --git a/docs/source/tests/execute_with_run_as_root_equals_true.rst b/docs/source/tests/execute_with_run_as_root_equals_true.rst deleted file mode 100644 index dde5cc94..00000000 --- a/docs/source/tests/execute_with_run_as_root_equals_true.rst +++ /dev/null @@ -1,51 +0,0 @@ - -execute_with_run_as_root_equals_true -==================================== - -Description ------------ -Running commands as root dramatically increase their potential risk. Running -commands with restricted user privileges provides defense in depth against -command injection attacks, or developer and configuration error. This plugin -test checks for specific methods being called with a keyword parameter -`run_as_root` set to True, a common OpenStack idiom. - - -Available Since ---------------- - - Bandit v0.10.0 - -Config Options --------------- -This test plugin takes a similarly named configuration block, -`execute_with_run_as_root_equals_true`, providing a list, `function_names`, of -function names. A call to any of these named functions will be checked for a -`run_as_root` keyword parameter, and if True, will report a Low severity -issue. - -.. code-block:: yaml - - 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 - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Execute with run_as_root=True identified, possible security issue. - Severity: Low Confidence: Medium - Location: ./examples/exec-as-root.py:26 - 25 nova_utils.trycmd('gcc --version') - 26 nova_utils.trycmd('gcc --version', run_as_root=True) - 27 - -References ----------- - - https://security.openstack.org/guidelines/dg_rootwrap-recommendations-and-plans.html - - https://security.openstack.org/guidelines/dg_use-oslo-rootwrap-securely.html diff --git a/docs/source/tests/flask_debug_true.rst b/docs/source/tests/flask_debug_true.rst deleted file mode 100644 index 43a912c8..00000000 --- a/docs/source/tests/flask_debug_true.rst +++ /dev/null @@ -1,39 +0,0 @@ - -flask_debug_true -================ - -Description ------------ -Running Flask applications in debug mode results in the Werkzeug debugger -being enabled. This includes a feature that allows arbitrary code execution. -Documentation for both Flask [1]_ and Werkzeug [2]_ strongly suggests that -debug mode should never be enabled on production systems. - -Operating a production server with debug mode enabled was the probable cause -of the Patreon breach in 2015 [3]_. - -Available Since ---------------- - - Bandit v0.15.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: A Flask app appears to be run with debug=True, which exposes - the Werkzeug debugger and allows the execution of arbitrary code. - Severity: High Confidence: High - Location: examples/flask_debug.py:10 - 9 #bad - 10 app.run(debug=True) - 11 - -References ----------- -.. [1] http://flask.pocoo.org/docs/0.10/quickstart/#debug-mode -.. [2] http://werkzeug.pocoo.org/docs/0.10/debug/ -.. [3] http://labs.detectify.com/post/130332638391/how-patreon-got-hacked-publicly-exposed-werkzeug diff --git a/docs/source/tests/hardcoded_bind_all_interfaces.rst b/docs/source/tests/hardcoded_bind_all_interfaces.rst deleted file mode 100644 index 7224dee8..00000000 --- a/docs/source/tests/hardcoded_bind_all_interfaces.rst +++ /dev/null @@ -1,33 +0,0 @@ - -hardcoded_bind_all_interfaces -============================= - -Description ------------ -Binding to all network interfaces can potentially open up a service to traffic -on unintended interfaces, that may not be properly documented or secured. This -plugin test looks for a string pattern "0.0.0.0" that may indicate a hardcoded -binding to all network interfaces. - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: Possible binding to all interfaces. - Severity: Medium Confidence: Medium - Location: ./examples/binding.py:4 - 3 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - 4 s.bind(('0.0.0.0', 31137)) - 5 s.bind(('192.168.0.1', 8080)) - -References ----------- - - __TODO__ : add best practice info on binding to all interfaces, and link here. diff --git a/docs/source/tests/hardcoded_password.rst b/docs/source/tests/hardcoded_password.rst deleted file mode 100644 index 571dc572..00000000 --- a/docs/source/tests/hardcoded_password.rst +++ /dev/null @@ -1,45 +0,0 @@ - -hardcoded_password -================== - -Description ------------ -The use of hard-coded passwords increases the possibility of password guessing -tremendously. This plugin test looks for all string literals and checks to see -if they exist in a list of likely default passwords. If they are found in the -list, a LOW severity issue is reported. - -Note: this test is very noisy and likely to result in many false positives. - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -This plugin test takes a similarly named config block, `hardcoded_password`. -Here a path, `word_list`, can be given to indicate where the default password -word list file may be found. - -.. code-block:: yaml - - 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" - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Possible hardcoded password '(root)' - Severity: Low Confidence: Low - Location: ./examples/hardcoded-passwords.py:5 - 4 def someFunction2(password): - 5 if password == "root": - 6 print("OK, logged in") - -References ----------- -- https://www.owasp.org/index.php/Use_of_hard-coded_password diff --git a/docs/source/tests/hardcoded_sql_expressions.rst b/docs/source/tests/hardcoded_sql_expressions.rst deleted file mode 100644 index 9fad036a..00000000 --- a/docs/source/tests/hardcoded_sql_expressions.rst +++ /dev/null @@ -1,48 +0,0 @@ -hardcoded_sql_expressions -========================= - -Description ------------ -An SQL injection attack consists of insertion or "injection" of a SQL query via -the input data given to an application. It is a very common attack vector. This -plugin test looks for strings that resemble SQL statements that are involved in -some form of string building operation. For example: - - - "SELECT %s FROM derp;" % var - - "SELECT thing FROM " + tab - - "SELECT " + val + " FROM " + tab + ... - -Unless care is taken to sanitize and control the input data when building such -SQL statement strings, an injection attack becomes possible. If strings of this -nature are discovered, a LOW confidence issue is reported. In order to boost -result confidence, this plugin test will also check to see if the discovered -string is in use with standard Python DBAPI calls `execute` or `executemany`. -If so, a MEDIUM issue is reported. For example: - - - cursor.execute("SELECT %s FROM derp;" % var) - - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -None - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Possible SQL injection vector through string-based query construction. - Severity: Medium Confidence: Low - Location: ./examples/sql_statements_without_sql_alchemy.py:4 - 3 query = "DELETE FROM foo WHERE id = '%s'" % identifier - 4 query = "UPDATE foo SET value = 'b' WHERE id = '%s'" % identifier - 5 - -References ----------- -- https://www.owasp.org/index.php/SQL_Injection -- https://security.openstack.org/guidelines/dg_parameterize-database-queries.html diff --git a/docs/source/tests/hardcoded_tmp_directory.rst b/docs/source/tests/hardcoded_tmp_directory.rst deleted file mode 100644 index fb2ff8e7..00000000 --- a/docs/source/tests/hardcoded_tmp_directory.rst +++ /dev/null @@ -1,45 +0,0 @@ - -hardcoded_tmp_directory -======================= - -Description ------------ -Safely creating a temporary file or directory means following a number of rules -(see the references for more details). This plugin test looks for strings -starting with (configurable) commonly used temporary paths, for example: - - - /tmp - - /var/tmp - - /dev/shm - - etc - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -This test plugin takes a similarly named config block, `hardcoded_tmp_directory`. -The config block provides a Python list, `tmp_dirs`, that lists string fragments -indicating possible temporary file paths. Any string starting with one of these -fragments will report a MEDIUM confidence issue. - -.. code-block:: yaml - - hardcoded_tmp_directory: - tmp_dirs: ['/tmp', '/var/tmp', '/dev/shm'] - - -Sample Output -------------- -.. code-block: none - - >> Issue: Probable insecure usage of temp file/directory. - Severity: Medium Confidence: Medium - Location: ./examples/hardcoded-tmp.py:1 - 1 f = open('/tmp/abc', 'w') - 2 f.write('def') - -References ----------- - - https://security.openstack.org/guidelines/dg_using-temporary-files-securely.html diff --git a/docs/source/tests/jinja2_autoescape_false.rst b/docs/source/tests/jinja2_autoescape_false.rst deleted file mode 100644 index 97a28ac0..00000000 --- a/docs/source/tests/jinja2_autoescape_false.rst +++ /dev/null @@ -1,59 +0,0 @@ - -jinja2_autoescape_false -======================= - -Description ------------ -Jinja2 is a Python HTML templating system. It is typically used to build web -applications, though appears in other places well, notably the Ansible -automation system. When configuring the Jinja2 environment, the option to use -autoescaping on input can be specified. When autoescaping is enabled, Jinja2 -will filter input strings to escape any HTML content submitted via template -variables. Without escaping HTML input the application becomes vulnerable to -Cross Site Scripting (XSS) attacks. - -Unfortunately, autoescaping is False by default. Thus this plugin test will warn -on omission of an autoescape setting, as well as an explicit setting of false. A -HIGH severity warning is generated in either of these scenarios. - -Available Since ---------------- - - Bandit v0.10.0 - -Config Options --------------- -None - - -Sample Output -------------- - -.. code-block:: none - - >> Issue: Using jinja2 templates with autoescape=False is dangerous and can - lead to XSS. Use autoescape=True to mitigate XSS vulnerabilities. - Severity: High Confidence: High - Location: ./examples/jinja2_templating.py:11 - 10 templateEnv = jinja2.Environment(autoescape=False, loader=templateLoader ) - 11 Environment(loader=templateLoader, - 12 load=templateLoader, - 13 autoescape=False) - 14 - - >> Issue: By default, jinja2 sets autoescape to False. Consider using - autoescape=True to mitigate XSS vulnerabilities. - Severity: High Confidence: High - Location: ./examples/jinja2_templating.py:15 - 14 - 15 Environment(loader=templateLoader, - 16 load=templateLoader) - 17 - - -References ----------- -- https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) -- https://realpython.com/blog/python/primer-on-jinja-templating/ -- http://jinja.pocoo.org/docs/dev/api/#autoescaping -- https://security.openstack.org -- https://security.openstack.org/guidelines/dg_cross-site-scripting-xss.html diff --git a/docs/source/tests/linux_commands_wildcard_injection.rst b/docs/source/tests/linux_commands_wildcard_injection.rst deleted file mode 100644 index 9fc62cb2..00000000 --- a/docs/source/tests/linux_commands_wildcard_injection.rst +++ /dev/null @@ -1,98 +0,0 @@ - -linux_commands_wildcard_injection -================================= - -Description ------------ -Python provides a number of methods that emulate the behavior of standard Linux -command line utilities. Like their Linux counterparts, these commands may take -a wildcard "\*" character in place of a file system path. This is interpreted -to mean "any and all files or folders" and can be used to build partially -qualified paths, such as "/home/user/\*". - -The use of partially qualified paths may result in unintended consequences if -an unexpected file or symlink is placed into the path location given. This -becomes particularly dangerous when combined with commands used to manipulate -file permissions or copy data off of a system. - -This test plugin looks for usage of the following commands in conjunction with -wild card parameters: - -- 'chown' -- 'chmod' -- 'tar' -- 'rsync' - -As well as any method configured in the shell or subprocess injection test -configurations. See also :doc:`start_process_with_partial_path` for related -issues with partial paths. - - -Available Since ---------------- - - Bandit v0.9.0 - - -Config Options --------------- -This plugin test shares a configuration with others in the same family, namely -`shell_injection`. This configuration is divided up into three sections, -`subprocess`, `shell` and `no_shell`. They each list Python calls that spawn -subprocesses, invoke commands within a shell, or invoke commands without a -shell (by replacing the calling process) respectively. - -This test will scan parameters of all methods in all sections. Note that methods -are fully qualified and de-aliased prior to checking. - -see also: - -- :doc:`start_process_with_partial_path` -- :doc:`start_process_with_a_shell` -- :doc:`start_process_with_no_shell` - -.. code-block:: yaml - - shell_injection: - # Start a process using the subprocess module, or one of its wrappers. - subprocess: - - subprocess.Popen - - subprocess.call - - # Start a process with a function vulnerable to shell injection. - shell: - - os.system - - os.popen - - 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 - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Possible wildcard injection in call: subprocess.Popen - Severity: High Confidence: Medium - Location: ./examples/wildcard-injection.py:8 - 7 o.popen2('/bin/chmod *') - 8 subp.Popen('/bin/chown *', shell=True) - 9 - - >> Issue: subprocess call - check for execution of untrusted input. - Severity: Low Confidence: High - Location: ./examples/wildcard-injection.py:11 - 10 # Not vulnerable to wildcard injection - 11 subp.Popen('/bin/rsync *') - 12 subp.Popen("/bin/chmod *") - - -References ----------- -- https://security.openstack.org -- https://en.wikipedia.org/wiki/Wildcard_character -- http://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt diff --git a/docs/source/tests/paramiko_calls.rst b/docs/source/tests/paramiko_calls.rst deleted file mode 100644 index 2c91be22..00000000 --- a/docs/source/tests/paramiko_calls.rst +++ /dev/null @@ -1,52 +0,0 @@ - -paramiko_calls -============== - -Description ------------ -Paramiko is a Python library designed to work with the SSH2 protocol for secure -(encrypted and authenticated) connections to remote machines. It is intended to -run commands on a remote host. These commands are run within a shell on the -target and are thus vulnerable to various shell injection attacks. Bandit -reports a MEDIUM issue when it detects the use of Paramiko's "exec_command" or -"invoke_shell" methods advising the user to check inputs are correctly -sanitized. - -See also: - -- :doc:`start_process_with_a_shell` -- :doc:`subprocess_popen_with_shell_equals_true` - - -Available Since ---------------- - - Bandit v0.12.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: Possible shell injection via Paramiko call, check inputs are properly sanitized. - Severity: Medium Confidence: Medium - Location: ./examples/paramiko_injection.py:4 - 3 # this is not safe - 4 paramiko.exec_command('something; reallly; unsafe') - 5 - - >> Issue: Possible shell injection via Paramiko call, check inputs are properly sanitized. - Severity: Medium Confidence: Medium - Location: ./examples/paramiko_injection.py:10 - 9 # this is not safe - 10 SSHClient.invoke_shell('something; bad; here\n') - 11 - -References ----------- - -- https://security.openstack.org -- https://github.com/paramiko/paramiko -- https://www.owasp.org/index.php/Command_Injection diff --git a/docs/source/tests/password_config_option_not_marked_secret.rst b/docs/source/tests/password_config_option_not_marked_secret.rst deleted file mode 100644 index 9148bc90..00000000 --- a/docs/source/tests/password_config_option_not_marked_secret.rst +++ /dev/null @@ -1,57 +0,0 @@ - -password_config_option_not_marked_secret -======================================== - -Description ------------ -Passwords are sensitive and must be protected appropriately. In OpenStack -Oslo there is an option to mark options "secret" which will ensure that they -are not logged. This plugin detects usages of oslo configuration functions -that appear to deal with strings ending in 'password' and flag usages where -they have not been marked secret. - -If such a value is found a MEDIUM severity error is generated. If 'False' or -'None' are explicitly set, Bandit will return a MEDIUM confidence issue. If -Bandit can't determine the value of secret it will return a LOW confidence -issue. - -Available Since ---------------- - - Bandit v0.10.0 - -Config Options --------------- -.. code-block:: yaml - - password_config_option_not_marked_secret: - function_names: - - oslo.config.cfg.StrOpt - - oslo_config.cfg.StrOpt - -Sample Output -------------- -.. code-block:: none - - >> Issue: [password_config_option_not_marked_secret] oslo config option - possibly not marked secret=True identified. - Severity: Medium Confidence: Low - Location: examples/secret-config-option.py:12 - 11 help="User's password"), - 12 cfg.StrOpt('nova_password', - 13 secret=secret, - 14 help="Nova user password"), - 15 ] - - >> Issue: [password_config_option_not_marked_secret] oslo config option not - marked secret=True identifed, security issue. - Severity: Medium Confidence: Medium - Location: examples/secret-config-option.py:21 - 20 help="LDAP ubind ser name"), - 21 cfg.StrOpt('ldap_password', - 22 help="LDAP bind user password"), - 23 cfg.StrOpt('ldap_password_attribute', - -References ----------- -- https://security.openstack.org/guidelines/dg_protect-sensitive-data-in-files.html -- http://docs.openstack.org/developer/oslo.config/cfg.html#special-handling-instructions diff --git a/docs/source/tests/request_with_no_cert_validation.rst b/docs/source/tests/request_with_no_cert_validation.rst deleted file mode 100644 index 3736c7b5..00000000 --- a/docs/source/tests/request_with_no_cert_validation.rst +++ /dev/null @@ -1,40 +0,0 @@ - -request_with_no_cert_validation -=============================== - -Description ------------ -Encryption in general is typically critical to the security of many -applications. Using TLS can greatly increase security by guaranteeing the -identity of the party you are communicating with. This is accomplished by one -or both parties presenting trusted certificates during the connection -initialization phase of TLS. - -When request methods are used certificates are validated automatically which is -the desired behavior. If certificate validation is explicitly turned off -Bandit will return a HIGH severity error. - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: [request_with_no_cert_validation] Requests call with verify=False - disabling SSL certificate checks, security issue. - Severity: High Confidence: High - Location: examples/requests-ssl-verify-disabled.py:4 - 3 requests.get('https://gmail.com', verify=True) - 4 requests.get('https://gmail.com', verify=False) - 5 requests.post('https://gmail.com', verify=True) - -References ----------- -- https://security.openstack.org/guidelines/dg_move-data-securely.html -- https://security.openstack.org/guidelines/dg_validate-certificates.html diff --git a/docs/source/tests/set_bad_file_permissions.rst b/docs/source/tests/set_bad_file_permissions.rst deleted file mode 100644 index 8147e0ed..00000000 --- a/docs/source/tests/set_bad_file_permissions.rst +++ /dev/null @@ -1,47 +0,0 @@ - -set_bad_file_permissions -======================== - -Description ------------ -POSIX based operating systems utilize a permissions model to protect access to -parts of the file system. This model supports three roles "owner", "group" -and "world" each role may have a combination of "read", "write" or "execute" -flags sets. Python provides ``chmod`` to manipulate POSIX style permissions. - -This plugin test looks for the use of ``chmod`` and will alert when it is used -to set particularly permissive control flags. A MEDIUM warning is generated if -a file is set to group executable and a HIGH warning is reported if a file is -set world writable. Warnings are given with HIGH confidence. - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: Probable insecure usage of temp file/directory. - Severity: Medium Confidence: Medium - Location: ./examples/os-chmod-py2.py:15 - 14 os.chmod('/etc/hosts', 0o777) - 15 os.chmod('/tmp/oh_hai', 0x1ff) - 16 os.chmod('/etc/passwd', stat.S_IRWXU) - - >> Issue: Chmod setting a permissive mask 0777 on file (key_file). - Severity: High Confidence: High - Location: ./examples/os-chmod-py2.py:17 - 16 os.chmod('/etc/passwd', stat.S_IRWXU) - 17 os.chmod(key_file, 0o777) - 18 - -References ----------- -- https://security.openstack.org/guidelines/dg_apply-restrictive-file-permissions.html -- https://en.wikipedia.org/wiki/File_system_permissions -- https://security.openstack.org diff --git a/docs/source/tests/ssl_with_bad_defaults.rst b/docs/source/tests/ssl_with_bad_defaults.rst deleted file mode 100644 index 580fc52d..00000000 --- a/docs/source/tests/ssl_with_bad_defaults.rst +++ /dev/null @@ -1,57 +0,0 @@ - -ssl_with_bad_defaults -===================== - -Description ------------ -Several highly publicized [1]_ [2]_, exploitable flaws have been discovered in -all versions of SSL and early versions of TLS. It is strongly recommended that -use of the following known broken protocol versions be avoided: - -- SSL v2 -- SSL v3 -- TLS v1 -- TLS v1.1 - -This plugin is part of a family of tests that detect the use of known bad -versions of SSL/TLS, please see :doc:`ssl_with_bad_version` for a complete -discussion. Specifically, this plugin test scans for Python methods with default -parameter values that specify the use of broken SSL/TLS protocol versions. -Currently, detection supports methods using Python's native SSL/TLS support and -the pyOpenSSL module. A MEDIUM severity warning will be reported whenever known -broken protocol versions are detected. - -See also: - -- :doc:`ssl_with_bad_version`. -- :doc:`ssl_with_no_version`. - - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -This test shares the configuration provided for the standard -:doc:`ssl_with_bad_version` test, please refer to it's -:ref:`bad_ssl_config_options` documentation. - -Sample Output -------------- -.. code-block:: none - - >> Issue: Function definition identified with insecure SSL/TLS protocol - version by default, possible security issue. - Severity: Medium Confidence: Medium - Location: ./examples/ssl-insecure-version.py:28 - 27 - 28 def open_ssl_socket(version=SSL.SSLv2_METHOD): - 29 pass - -References ----------- -- [1] http://heartbleed.com/ -- [2] https://poodlebleed.com/ -- https://security.openstack.org/ -- https://security.openstack.org/guidelines/dg_move-data-securely.html diff --git a/docs/source/tests/ssl_with_bad_version.rst b/docs/source/tests/ssl_with_bad_version.rst deleted file mode 100644 index 6a7a2e76..00000000 --- a/docs/source/tests/ssl_with_bad_version.rst +++ /dev/null @@ -1,83 +0,0 @@ - -ssl_with_bad_version -==================== - -Description ------------ -Several highly publicized [1]_ [2]_, exploitable flaws have been discovered in -all versions of SSL and early versions of TLS. It is strongly recommended that -use of the following known broken protocol versions be avoided: - -- SSL v2 -- SSL v3 -- TLS v1 -- TLS v1.1 - -This plugin test scans for calls to Python methods with parameters that indicate -the used broken SSL/TLS protocol versions. Currently, detection supports methods -using Python's native SSL/TLS support and the pyOpenSSL module. A HIGH severity -warning will be reported whenever known broken protocol versions are detected. - -It is worth noting that native support for TLS 1.2 is only available in more -recent Python versions, specifically 2.7.9 and up, and 3.x - -See also: - -- :doc:`ssl_with_bad_defaults`. -- :doc:`ssl_with_no_version`. - -A note on 'SSLv23' ------------------- -Amongst the available SSL/TLS versions provided by Python/pyOpenSSL there exists -the option to use SSLv23. This very poorly named option actually means "use the -highest version of SSL/TLS supported by both the server and client". This may -(and should be) a version well in advance of SSL v2 or v3. Bandit can scan for -the use of SSLv23 if desired, but its detection does not necessarily indicate a -problem. - -When using SSLv23 it is important to also provide flags to explicitly exclude -bad versions of SSL/TLS from the protocol versions considered. Both the Python -native and pyOpenSSL modules provide the ``OP_NO_SSLv2`` and ``OP_NO_SSLv3`` -flags for this purpose. - - -Available Since ---------------- - - Bandit v0.9.0 - - .. _bad_ssl_config_options: - -Config Options --------------- -.. code-block:: yaml - - 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 - - -Sample Output -------------- -.. code-block:: none - - >> Issue: ssl.wrap_socket call with insecure SSL/TLS protocol version - identified, security issue. - Severity: High Confidence: High - Location: ./examples/ssl-insecure-version.py:13 - 12 # strict tests - 13 ssl.wrap_socket(ssl_version=ssl.PROTOCOL_SSLv3) - 14 ssl.wrap_socket(ssl_version=ssl.PROTOCOL_TLSv1) - -References ----------- -- [1] http://heartbleed.com/ -- [2] https://poodlebleed.com/ -- https://security.openstack.org/ -- https://security.openstack.org/guidelines/dg_move-data-securely.html - diff --git a/docs/source/tests/ssl_with_no_version.rst b/docs/source/tests/ssl_with_no_version.rst deleted file mode 100644 index 8b5db223..00000000 --- a/docs/source/tests/ssl_with_no_version.rst +++ /dev/null @@ -1,59 +0,0 @@ - -ssl_with_no_version -=================== - -Description ------------ -Several highly publicized [1]_ [2]_, exploitable flaws have been discovered in -all versions of SSL and early versions of TLS. It is strongly recommended that -use of the following known broken protocol versions be avoided: - -- SSL v2 -- SSL v3 -- TLS v1 -- TLS v1.1 - -This plugin is part of a family of tests that detect the use of known bad -versions of SSL/TLS, please see :doc:`ssl_with_bad_version` for a complete -discussion. Specifically, This plugin test scans for specific methods in -Python's native SSL/TLS support and the pyOpenSSL module that configure the -version of SSL/TLS protocol to use. These methods are known to provide default -value that maximize compatibility, but permit use of the aforementioned broken -protocol versions. A LOW severity warning will be reported whenever this is -detected. - -See also: - -- :doc:`ssl_with_bad_version`. -- :doc:`ssl_with_bad_defaults`. - - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -This test shares the configuration provided for the standard -:doc:`ssl_with_bad_version` test, please refer to it's -:ref:`bad_ssl_config_options` documentation. - -Sample Output -------------- -.. code-block:: none - - >> Issue: ssl.wrap_socket call with no SSL/TLS protocol version specified, - the default SSLv23 could be insecure, possible security issue. - Severity: Low Confidence: Medium - Location: ./examples/ssl-insecure-version.py:23 - 22 - 23 ssl.wrap_socket() - 24 - -References ----------- -- [1] http://heartbleed.com/ -- [2] https://poodlebleed.com/ -- https://security.openstack.org/ -- https://security.openstack.org/guidelines/dg_move-data-securely.html - diff --git a/docs/source/tests/start_process_with_a_shell.rst b/docs/source/tests/start_process_with_a_shell.rst deleted file mode 100644 index c435c9de..00000000 --- a/docs/source/tests/start_process_with_a_shell.rst +++ /dev/null @@ -1,73 +0,0 @@ - -start_process_with_a_shell -============================================== - -Description ------------ -Python possesses many mechanisms to invoke an external executable. However, -doing so may present a security issue if appropriate care is not taken to -sanitize any user provided or variable input. - -This plugin test is part of a family of tests built to check for process -spawning and warn appropriately. Specifically, this test looks for the spawning -of a subprocess using a command shell. This type of subprocess invocation is -dangerous as it is vulnerable to various shell injection attacks. Great care -should be taken to sanitize all input in order to mitigate this risk. Calls of -this type are identified by the use of certain commands which are known to use -shells. Bandit will report a MEDIUM severity warning. - -See also: - -- :doc:`linux_commands_wildcard_injection`. -- :doc:`subprocess_without_shell_equals_true`. -- :doc:`start_process_with_no_shell`. -- :doc:`start_process_with_partial_path`. -- :doc:`subprocess_popen_with_shell_equals_true`. - -Available Since ---------------- - - Bandit v0.10.0 - -Config Options --------------- -This plugin test shares a configuration with others in the same family, namely -`shell_injection`. This configuration is divided up into three sections, -`subprocess`, `shell` and `no_shell`. They each list Python calls that spawn -subprocesses, invoke commands within a shell, or invoke commands without a -shell (by replacing the calling process) respectively. - -This plugin specifically scans for methods listed in `shell` section. - -.. code-block:: yaml - - 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 - -Sample Output -------------- -.. code-block:: none - - >> Issue: Starting a process with a shell: check for injection. - Severity: Medium Confidence: Medium - Location: examples/os_system.py:3 - 2 - 3 os.system('/bin/echo hi') - -References ----------- -- https://security.openstack.org -- https://docs.python.org/2/library/os.html#os.system -- https://docs.python.org/2/library/subprocess.html#frequently-used-arguments -- https://security.openstack.org/guidelines/dg_use-subprocess-securely.html diff --git a/docs/source/tests/start_process_with_no_shell.rst b/docs/source/tests/start_process_with_no_shell.rst deleted file mode 100644 index f4a7d803..00000000 --- a/docs/source/tests/start_process_with_no_shell.rst +++ /dev/null @@ -1,76 +0,0 @@ - -start_process_with_no_shell -============================================== - -Description ------------ -Python possesses many mechanisms to invoke an external executable. However, -doing so may present a security issue if appropriate care is not taken to -sanitize any user provided or variable input. - -This plugin test is part of a family of tests built to check for process -spawning and warn appropriately. Specifically, this test looks for the spawning -of a subprocess in a way that doesn't use a shell. Although this is generally -safe, it maybe useful for penetration testing workflows to track where external -system calls are used. As such a LOW severity message is generated. - -See also: - -- :doc:`linux_commands_wildcard_injection`. -- :doc:`subprocess_without_shell_equals_true`. -- :doc:`start_process_with_a_shell`. -- :doc:`start_process_with_partial_path`. -- :doc:`subprocess_popen_with_shell_equals_true`. - -Available Since ---------------- - - Bandit v0.10.0 - -Config Options --------------- -This plugin test shares a configuration with others in the same family, namely -`shell_injection`. This configuration is divided up into three sections, -`subprocess`, `shell` and `no_shell`. They each list Python calls that spawn -subprocesses, invoke commands within a shell, or invoke commands without a -shell (by replacing the calling process) respectively. - -This plugin specifically scans for methods listed in `no_shell` section. - -.. code-block:: yaml - - 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 -Sample Output -------------- -.. code-block:: none - - >> Issue: [start_process_with_no_shell] Starting a process without a shell. - Severity: Low Confidence: Medium - Location: examples/os-spawn.py:8 - 7 os.spawnv(mode, path, args) - 8 os.spawnve(mode, path, args, env) - 9 os.spawnvp(mode, file, args) - -References ----------- -- https://security.openstack.org -- https://docs.python.org/2/library/os.html#os.system -- https://docs.python.org/2/library/subprocess.html#frequently-used-arguments -- https://security.openstack.org/guidelines/dg_use-subprocess-securely.html diff --git a/docs/source/tests/start_process_with_partial_path.rst b/docs/source/tests/start_process_with_partial_path.rst deleted file mode 100644 index 1780c285..00000000 --- a/docs/source/tests/start_process_with_partial_path.rst +++ /dev/null @@ -1,74 +0,0 @@ - -start_process_with_partial_path -=============================== - -Description ------------ -Python possesses many mechanisms to invoke an external executable. If the -desired executable path is not fully qualified relative to the filesystem root -then this may present a potential security risk. - -In POSIX environments, the `PATH` environment variable is used to specify a -set of standard locations that will be searched for the first matching named -executable. While convenient, this behavior may allow a malicious actor to -exert control over a system. If they are able to adjust the contents of the -`PATH` variable, or manipulate the file system, then a bogus executable may be -discovered in place of the desired one. This executable will be invoked with the -user privileges of the Python process that spawned it, potentially a highly -privileged user. - -This test will scan the parameters of all configured Python methods, looking -for paths that do not start at the filesystem root, that is, do not have a -leading '/' character. - -Available Since ---------------- - - Bandit v0.13.0 - -Config Options --------------- -This plugin test shares a configuration with others in the same family, namely -`shell_injection`. This configuration is divided up into three sections, -`subprocess`, `shell` and `no_shell`. They each list Python calls that spawn -subprocesses, invoke commands within a shell, or invoke commands without a -shell (by replacing the calling process) respectively. - -This test will scan parameters of all methods in all sections. Note that methods -are fully qualified and de-aliased prior to checking. - -.. code-block:: yaml - - shell_injection: - # Start a process using the subprocess module, or one of its wrappers. - subprocess: - - subprocess.Popen - - subprocess.call - - # Start a process with a function vulnerable to shell injection. - shell: - - os.system - - os.popen - - 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 - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Starting a process with a partial executable path - Severity: Low Confidence: High - Location: ./examples/partial_path_process.py:3 - 2 from subprocess import Popen as pop - 3 pop('gcc --version', shell=False) - -References ----------- -- https://security.openstack.org -- https://docs.python.org/2/library/os.html#process-management diff --git a/docs/source/tests/subprocess_popen_with_shell_equals_true.rst b/docs/source/tests/subprocess_popen_with_shell_equals_true.rst deleted file mode 100644 index da69e4de..00000000 --- a/docs/source/tests/subprocess_popen_with_shell_equals_true.rst +++ /dev/null @@ -1,92 +0,0 @@ - -subprocess_popen_with_shell_equals_true -======================================= - -Description ------------ -Python possesses many mechanisms to invoke an external executable. However, -doing so may present a security issue if appropriate care is not taken to -sanitize any user provided or variable input. - -This plugin test is part of a family of tests built to check for process -spawning and warn appropriately. Specifically, this test looks for the spawning -of a subprocess using a command shell. This type of subprocess invocation is -dangerous as it is vulnerable to various shell injection attacks. Great care -should be taken to sanitize all input in order to mitigate this risk. Calls of -this type are identified by a parameter of "shell=True" being given. - -Additionally, this plugin scans the command string given and adjusts its -reported severity based on how it is presented. If the command string is a -simple static string containing no special shell characters, then the resulting -issue has low severity. If the string is static, but contains shell formatting -characters or wildcards, then the reported issue is medium. Finally, if the -string is computed using Python's string manipulation or formatting operations, -then the reported issue has high severity. These severity levels reflect the -likelihood that the code is vulnerable to injection. - -See also: - -- :doc:`linux_commands_wildcard_injection`. -- :doc:`subprocess_without_shell_equals_true`. -- :doc:`start_process_with_no_shell`. -- :doc:`start_process_with_a_shell`. -- :doc:`start_process_with_partial_path`. - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -This plugin test shares a configuration with others in the same family, namely -`shell_injection`. This configuration is divided up into three sections, -`subprocess`, `shell` and `no_shell`. They each list Python calls that spawn -subprocesses, invoke commands within a shell, or invoke commands without a -shell (by replacing the calling process) respectively. - -This plugin specifically scans for methods listed in `subprocess` section that -have shell=True specified. - -.. code-block:: yaml - - shell_injection: - - # Start a process using the subprocess module, or one of its wrappers. - subprocess: - - subprocess.Popen - - subprocess.call - - -Sample Output -------------- -.. code-block:: none - - >> Issue: subprocess call with shell=True seems safe, but may be changed in - the future, consider rewriting without shell - Severity: Low Confidence: High - Location: ./examples/subprocess_shell.py:21 - 20 subprocess.check_call(['/bin/ls', '-l'], shell=False) - 21 subprocess.check_call('/bin/ls -l', shell=True) - 22 - - >> Issue: call with shell=True contains special shell characters, consider - moving extra logic into Python code - Severity: Medium Confidence: High - Location: ./examples/subprocess_shell.py:26 - 25 - 26 subprocess.Popen('/bin/ls *', shell=True) - 27 subprocess.Popen('/bin/ls %s' % ('something',), shell=True) - - >> Issue: subprocess call with shell=True identified, security issue. - Severity: High Confidence: High - Location: ./examples/subprocess_shell.py:27 - 26 subprocess.Popen('/bin/ls *', shell=True) - 27 subprocess.Popen('/bin/ls %s' % ('something',), shell=True) - 28 subprocess.Popen('/bin/ls {}'.format('something'), shell=True) - -References ----------- -- https://security.openstack.org -- https://docs.python.org/2/library/subprocess.html#frequently-used-arguments -- https://security.openstack.org/guidelines/dg_use-subprocess-securely.html -- https://security.openstack.org/guidelines/dg_avoid-shell-true.html diff --git a/docs/source/tests/subprocess_without_shell_equals_true.rst b/docs/source/tests/subprocess_without_shell_equals_true.rst deleted file mode 100644 index 6d1666a9..00000000 --- a/docs/source/tests/subprocess_without_shell_equals_true.rst +++ /dev/null @@ -1,68 +0,0 @@ - -subprocess_without_shell_equals_true -============================================== - -Description ------------ -Python possesses many mechanisms to invoke an external executable. However, -doing so may present a security issue if appropriate care is not taken to -sanitize any user provided or variable input. - -This plugin test is part of a family of tests built to check for process -spawning and warn appropriately. Specifically, this test looks for the spawning -of a subprocess without the use of a command shell. This type of subprocess -invocation is not vulnerable to shell injection attacks, but care should still -be taken to ensure validity of input. - -Because this is a lesser issue than that described in -`subprocess_popen_with_shell_equals_true` a LOW severity warning is reported. - -See also: - -- :doc:`linux_commands_wildcard_injection`. -- :doc:`subprocess_popen_with_shell_equals_true`. -- :doc:`start_process_with_no_shell`. -- :doc:`start_process_with_a_shell`. -- :doc:`start_process_with_partial_path`. - -Available Since ---------------- - - Bandit v0.9.0 - -Config Options --------------- -This plugin test shares a configuration with others in the same family, namely -`shell_injection`. This configuration is divided up into three sections, -`subprocess`, `shell` and `no_shell`. They each list Python calls that spawn -subprocesses, invoke commands within a shell, or invoke commands without a -shell (by replacing the calling process) respectively. - -This plugin specifically scans for methods listed in `subprocess` section that -have shell=False specified. - -.. code-block:: yaml - - shell_injection: - # Start a process using the subprocess module, or one of its wrappers. - subprocess: - - subprocess.Popen - - subprocess.call - - -Sample Output -------------- -.. code-block:: none - - >> Issue: subprocess call - check for execution of untrusted input. - Severity: Low Confidence: High - Location: ./examples/subprocess_shell.py:23 - 22 - 23 subprocess.check_output(['/bin/ls', '-l']) - 24 - -References ----------- -- https://security.openstack.org -- https://docs.python.org/2/library/subprocess.html#frequently-used-arguments -- https://security.openstack.org/guidelines/dg_avoid-shell-true.html -- https://security.openstack.org/guidelines/dg_use-subprocess-securely.html diff --git a/docs/source/tests/try_except_pass.rst b/docs/source/tests/try_except_pass.rst deleted file mode 100644 index 80aad947..00000000 --- a/docs/source/tests/try_except_pass.rst +++ /dev/null @@ -1,66 +0,0 @@ - -try_except_pass -=============== - -Description ------------ -Errors in Python code bases are typically communicated using ``Exceptions``. -An exception object is 'raised' in the event of an error and can be 'caught' at -a later point in the program, typically some error handling or logging action -will then be performed. - -However, it is possible to catch an exception and silently ignore it. This is -illustrated with the following example - -.. code-block:: python - - try: - do_some_stuff() - except Exception: - pass - -This pattern is considered bad practice in general, but also represents a -potential security issue. A larger than normal volume of errors from a service -can indicate an attempt is being made to disrupt or interfere with it. Thus -errors should, at the very least, be logged. - -There are rare situations where it is desirable to suppress errors, but this is -typically done with specific exception types, rather than the base Exception -class (or no type). To accommodate this, the test may be configured to ignore -'try, except, pass' where the exception is typed. For example, the following -would not generate a warning if the configuration option -``checked_typed_exception`` is set to False: - -.. code-block:: python - - try: - do_some_stuff() - except ZeroDivisionError: - pass - -Available Since ---------------- - - Bandit v0.13.0 - -Config Options --------------- -.. code-block:: yaml - - try_except_pass: - check_typed_exception: True - - -Sample Output -------------- -.. code-block:: none - - >> Issue: Try, Except, Pass detected. - Severity: Low Confidence: High - Location: ./examples/try_except_pass.py:4 - 3 a = 1 - 4 except: - 5 pass - -References ----------- -- https://security.openstack.org diff --git a/docs/source/tests/use_of_mako_templates.rst b/docs/source/tests/use_of_mako_templates.rst deleted file mode 100644 index 905033e6..00000000 --- a/docs/source/tests/use_of_mako_templates.rst +++ /dev/null @@ -1,47 +0,0 @@ - -use_of_mako_templates -===================== - -Description ------------ -Mako is a Python templating system often used to build web applications. It is -the default templating system used in Pylons and Pyramid. Unlike Jinja2 (an -alternative templating system), Mako has no environment wide variable escaping -mechanism. Because of this, all input variables must be carefully escaped before -use to prevent possible vulnerabilities to Cross Site Scripting (XSS) attacks. - -See also: - -- :doc:`jinja2_autoescape_false`. - - -Available Since ---------------- - - Bandit v0.10.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: Mako templates allow HTML/JS rendering by default and are - inherently open to XSS attacks. Ensure variables in all templates are - properly sanitized via the 'n', 'h' or 'x' flags (depending on context). - For example, to HTML escape the variable 'data' do ${ data |h }. - Severity: Medium Confidence: High - Location: ./examples/mako_templating.py:10 - 9 - 10 mako.template.Template("hern") - 11 template.Template("hern") - - -References ----------- -- http://www.makotemplates.org/ -- https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) -- https://security.openstack.org -- https://security.openstack.org/guidelines/dg_cross-site-scripting-xss.html - diff --git a/docs/source/tests/weak_cryptographic_key.rst b/docs/source/tests/weak_cryptographic_key.rst deleted file mode 100644 index a6d2027c..00000000 --- a/docs/source/tests/weak_cryptographic_key.rst +++ /dev/null @@ -1,36 +0,0 @@ - -weak_cryptographic_key -====================== - -Description ------------ -As computational power increases, so does the ability to break ciphers with -smaller key lengths. The recommended key length size is 2048 and higher. 1024 -bits and below are now considered breakable. This plugin test checks for use -of any key less than 2048 bits and returns a high severity error if lower than -1024 and a medium severity error greater than 1024 but less than 2048. - -Available Since ---------------- - - Bandit v0.14.0 - -Config Options --------------- -None - -Sample Output -------------- -.. code-block:: none - - >> Issue: DSA key sizes below 1024 bits are considered breakable. - Severity: High Confidence: High - Location: examples/weak_cryptographic_key_sizes.py:36 - 35 # Also incorrect: without keyword args - 36 dsa.generate_private_key(512, - 37 backends.default_backend()) - 38 rsa.generate_private_key(3, - -References ----------- - - http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf - - https://security.openstack.org/guidelines/dg_strong-crypto.html diff --git a/setup.cfg b/setup.cfg index 949fad38..c6fc5932 100644 --- a/setup.cfg +++ b/setup.cfg @@ -113,8 +113,8 @@ data_files = [build_sphinx] all_files = 1 -build-dir = docs/build -source-dir = docs/source +build-dir = doc/build +source-dir = doc/source [pbr] autodoc_tree_index_modules = True