在python中使用shell = True的子进程的清理输入

时间:2016-05-31 17:42:11

标签: python shell subprocess openstack popen

我有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.splitshlex.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

时删除此错误

1 个答案:

答案 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的原因。