不受控制的命令行¶
ID: py/command-line-injection
Kind: path-problem
Security severity: 9.8
Severity: error
Precision: high
Tags:
- correctness
- security
- external/cwe/cwe-078
- external/cwe/cwe-088
Query suites:
- python-code-scanning.qls
- python-security-extended.qls
- python-security-and-quality.qls
将用户输入直接传递给 exec
、eval
或其他执行命令的库例程的代码,允许用户执行恶意代码。
建议¶
如果可能,使用硬编码的字符串字面量来指定要运行的命令或要加载的库。不要将用户输入直接传递给进程或库函数,而是检查用户输入,然后在硬编码的字符串字面量中进行选择。
如果无法在编译时确定适用的库或命令,请添加代码以验证用户输入字符串在使用之前是否安全。
示例¶
以下示例展示了两个函数。第一个函数不安全,因为它接受一个可以被用户更改的 shell 脚本,并将其直接传递给 subprocess.call()
,而没有事先检查。第二个函数是安全的,因为它从预定义的允许列表中选择命令。
urlpatterns = [
# Route to command_execution
url(r'^command-ex1$', command_execution_unsafe, name='command-execution-unsafe'),
url(r'^command-ex2$', command_execution_safe, name='command-execution-safe')
]
COMMANDS = {
"list" :"ls",
"stat" : "stat"
}
def command_execution_unsafe(request):
if request.method == 'POST':
action = request.POST.get('action', '')
#BAD -- No sanitizing of input
subprocess.call(["application", action])
def command_execution_safe(request):
if request.method == 'POST':
action = request.POST.get('action', '')
#GOOD -- Use an allowlist
subprocess.call(["application", COMMANDS[action]])