updates
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
#
|
||||
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
r"""
|
||||
========================================
|
||||
B609: Test for use of wildcard injection
|
||||
========================================
|
||||
|
||||
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
|
||||
|
||||
|
||||
:Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
>> Issue: Possible wildcard injection in call: subprocess.Popen
|
||||
Severity: High Confidence: Medium
|
||||
CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
|
||||
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
|
||||
CWE-78 (https://cwe.mitre.org/data/definitions/78.html)
|
||||
Location: ./examples/wildcard-injection.py:11
|
||||
10 # Not vulnerable to wildcard injection
|
||||
11 subp.Popen('/bin/rsync *')
|
||||
12 subp.Popen("/bin/chmod *")
|
||||
|
||||
|
||||
.. seealso::
|
||||
|
||||
- https://security.openstack.org
|
||||
- https://en.wikipedia.org/wiki/Wildcard_character
|
||||
- https://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt
|
||||
- https://cwe.mitre.org/data/definitions/78.html
|
||||
|
||||
.. versionadded:: 0.9.0
|
||||
|
||||
.. versionchanged:: 1.7.3
|
||||
CWE information added
|
||||
|
||||
"""
|
||||
import bandit
|
||||
from bandit.core import issue
|
||||
from bandit.core import test_properties as test
|
||||
from bandit.plugins import injection_shell # NOTE(tkelsey): shared config
|
||||
|
||||
gen_config = injection_shell.gen_config
|
||||
|
||||
|
||||
@test.takes_config("shell_injection")
|
||||
@test.checks("Call")
|
||||
@test.test_id("B609")
|
||||
def linux_commands_wildcard_injection(context, config):
|
||||
if not ("shell" in config and "subprocess" in config):
|
||||
return
|
||||
|
||||
vulnerable_funcs = ["chown", "chmod", "tar", "rsync"]
|
||||
if context.call_function_name_qual in config["shell"] or (
|
||||
context.call_function_name_qual in config["subprocess"]
|
||||
and context.check_call_arg_value("shell", "True")
|
||||
):
|
||||
if context.call_args_count >= 1:
|
||||
call_argument = context.get_call_arg_at_position(0)
|
||||
argument_string = ""
|
||||
if isinstance(call_argument, list):
|
||||
for li in call_argument:
|
||||
argument_string += f" {li}"
|
||||
elif isinstance(call_argument, str):
|
||||
argument_string = call_argument
|
||||
|
||||
if argument_string != "":
|
||||
for vulnerable_func in vulnerable_funcs:
|
||||
if (
|
||||
vulnerable_func in argument_string
|
||||
and "*" in argument_string
|
||||
):
|
||||
return bandit.Issue(
|
||||
severity=bandit.HIGH,
|
||||
confidence=bandit.MEDIUM,
|
||||
cwe=issue.Cwe.IMPROPER_WILDCARD_NEUTRALIZATION,
|
||||
text="Possible wildcard injection in call: %s"
|
||||
% context.call_function_name_qual,
|
||||
lineno=context.get_lineno_for_call_arg("shell"),
|
||||
)
|
||||
Reference in New Issue
Block a user