【问题标题】:Python3 - Sanitizing user input for shell usePython3 - 清理用户输入以供 shell 使用
【发布时间】:2021-12-07 10:36:50
【问题描述】:

我正忙于编写需要用户输入的 Python3 脚本,输入用作传递给 shell 的命令中的参数。

该脚本仅供受信任的内部用户使用 - 但我宁愿有一些应急措施来确保命令的有效执行。

示例 1:

import subprocess

user_input = '/tmp/file.txt'
subprocess.Popen(['cat', user_input])

这将输出'/tmp/file.txt'的内容

示例 2:

import subprocess

user_input = '/tmp/file.txt && rm -rf /'
subprocess.Popen(['cat', user_input])

结果(如预期):

cat: /tmp/file.txt && rm -rf /: No such file or directory

这是一种可接受的输入净化方法吗?根据最佳实践,除此之外我还应该做些什么吗?

【问题讨论】:

  • 不,不是来自文件。输入是通过终端中的交互式菜单输入的。我只是简化了我的问题。变量“user_input”只是表示用户应该输入到应用程序中的任何内容。

标签: python-3.x bash shell input sanitization


【解决方案1】:

你选择的方法,

import subprocess
user_input = 'string'
subprocess.Popen(['command', user_input])

非常好,因为command 是静态的,user_input 作为单个参数传递给command。只要你不做一些非常愚蠢的事情,比如

subprocess.Popen(['bash', '-c', user_input])

您应该注意安全。


对于需要多个参数的命令,我建议您向用户请求多个输入,例如这样做

user_input1='file1.txt'
user_input2='file2.txt'
subprocess.Popen(['cp', user_input1, user_input2])

而不是这个

user_input="file1.txt file2.txt"
subprocess.Popen(['cp'] + user_input.split())

如果您想进一步提高安全性,您可以:

  • 明确设置shell=False(以确保您从不运行shell命令;这已经是当前默认值,但默认值可能会随着时间而改变):
    subprocess.Popen(['command', user_input], shell=False)
    
  • 使用command 的绝对路径(以防止通过PATH 注入恶意可执行文件):
    subprocess.Popen(['/usr/bin/command', user_input])
    
  • 明确指示支持它的命令停止解析选项,例如
    subprocess.Popen(['rm', '--', user_input1, user_input2])
    
  • 尽可能多地在本地做,例如cat /tmp/file.txt 可以改用几行 Python 代码来完成(如果这是一个因素,这也将增加可移植性)

【讨论】:

    猜你喜欢
    • 2013-11-17
    • 1970-01-01
    • 2013-09-14
    • 2015-08-16
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-02
    • 2014-09-08
    相关资源
    最近更新 更多