【问题标题】:Sanitized input for subprocess with shell=True in python在python中使用shell = True对子进程进行消毒输入
【发布时间】:2016-05-31 17:42:10
【问题描述】:

我有 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时有什么办法可以消除这个错误

【问题讨论】:

  • bandit 无法确定命令参数是否经过充分清理;它只能检测到您使用Popen 的方式可能 是一个安全问题。你最好离开shell=False,自己准备cmd,以供exec直接使用。
  • 分析器无法判断您正在运行的命令是否是您想要运行的命令。根据您的操作,对解释器进行沙箱处理(例如使用codejail)可能是合适的或必要的。这涉及输入清理和严格控制的操作系统权限的组合。
  • @chepner,exec 表示,subprocess.exec ?
  • exec 表示实际用于执行命令的任何底层系统调用。使用带有shell=False 的列表更安全,因为没有任何东西可以解释参数;字符串按原样传递。
  • 使用shell=True 是否安全取决于cmd 的来源(您是否使用用户输入来构造它?)。在这里打电话shlex.quote()shlex.split()是没有意义和错误的。

标签: python shell subprocess openstack popen


【解决方案1】:

所以,用户输入他想要运行的命令

如果用户已经可以运行包括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 允许用户在这种情况下运行任意命令,即使它不是有意的。它被称为 shell 注入。

您可以调用pipes.quote(query),以避免幼稚攻击,但在一般情况下它可能会失败,这就是为什么如果输入不是来自受信任的来源,应避免使用shell=True

【讨论】:

  • 谢谢塞巴斯蒂安,我会想办法删除shell=True,但在创建shell=False 之后,bandit 仍然会为此引发错误。它将Severity 级别从Hight 更改为Low,也没有办法删除它?
  • @Lafada 1- 我的回答是,在您的情况下删除 shell=True 可能毫无意义——它不会使您的代码更安全。 2-如何禁用强盗的警告是一个有效但不同的问题。您应该将其作为一个单独的问题提出。
猜你喜欢
  • 2012-04-23
  • 2017-02-09
  • 2015-08-30
  • 1970-01-01
  • 2017-03-01
  • 2023-03-06
  • 2023-03-20
相关资源
最近更新 更多