我有python脚本,它有代码。
...
...
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
output, error = p.communicate()
...
...
当我运行bandit
时,它会出错。
>> Issue: [B602:subprocess_popen_with_shell_equals_true] subprocess call with shell=True identified, security issue.
Severity: High Confidence: High
Location: mypackage/myfile.py:123
123 stderr=subprocess.PIPE,
124 shell=True)
125 output, error = p.communicate()
然后我做了一些谷歌,并发现,我必须清理我的输入并使用shlex.split
和shlex.quote
我可以消毒它。
我将代码更改为。
...
...
p = subprocess.Popen(shlex.split(shlex.quote(cmd)),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
output, error = p.communicate()
...
...
但是我仍然遇到同样的错误,有没有办法在运行bandit -r mypackage/myfile.py
答案 0 :(得分:2)
因此,用户输入他想要运行的命令
如果用户已经可以运行包含bash
的任何命令,则bandit
关于shell=True
的警告不适用。
如果允许用户仅为固定命令选择一些参数,例如grep
命令的搜索查询,则警告是有意义的:
rc = call(['grep', '-e', query, path])
用户指定的query
;它不会让它运行其他命令(只运行grep
)。
将其与shell=True
:
rc = call("grep -e '%s' '%s'" % (query, path), shell=True) #XXX don't do it
用户可以传递会产生query = "a' /dev/null; rm -rf '"
命令的grep -e 'a' /dev/null; rm -rf '' 'path'
。
shell=True
允许用户在这种情况下运行任意命令,即使它不是预期的。它被称为壳注射。
您可以调用pipes.quote(query)
,以避免天真的攻击,但在一般情况下可能会失败,这就是为什么如果输入不是来自可靠来源应该避免shell=True
的原因。