2016-05-31 79 views
0

我有python脚本,它有代码。在shell中使用shell = True的子进程的消毒输入

... 
... 
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

+2

'bandit'无法确定命令参数是否被充分消毒;它只能检测到你正在使用'Popen',这可能会成为一个安全问题。你最好离开'shell = False'并准备'cmd',这个方式可以直接被'exec'使用。 – chepner

+0

分析器无法判断您运行的命令是否是您希望运行的命令。根据你正在做什么,沙盒化intepreter(例如[codejail](https://github.com/edx/codejail))可能是合适的或必要的。这涉及输入消毒和严格控制的操作系统权限的组合。 – gecko

+0

@chepner,'exec'的意思是'subprocess.exec'? – Nilesh

回答

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应该避免,如果输入不是来自可信来源。

+0

谢谢塞巴斯蒂安,我会试图找出某些东西去除'shell = True',但是在做出shell = False之后,仍然会出现'bandit'的错误。它会将'严重性'级别从'Hight'更改为'低级',那么还有没有办法将其删除呢? – Nilesh

+0

@Lafada 1-我的答案是,在你的情况下删除'shell = True'很可能毫无意义 - 它不会让你的代码更安全。 2-如何禁用强盗的警告是一个有效但不同的问题。你应该把它作为一个单独的问题来提出。 – jfs

+0

这里我的新问题http://stackoverflow.com/questions/37661695/remove-bandit-notify-for-paramiko-and-subprocess-popen :) – Nilesh