python使用不带shell的popen或assert来提高安全性

python使用不带shell的popen或assert来提高安全性,python,regex,shell,assert,popen,Python,Regex,Shell,Assert,Popen,使用subprocess.popen调用脚本中的外部程序。在没有shell=True的情况下,我无法让它工作,并且添加了一个assert语句来降低危险性(我认为) 相关代码行: import subprocess import re import argparse parser = argparse.ArgumentParser(description="options") parser.add_argument("-p", "--prefix", help="prefix for outpu

使用subprocess.popen调用脚本中的外部程序。在没有shell=True的情况下,我无法让它工作,并且添加了一个assert语句来降低危险性(我认为)

相关代码行:

import subprocess
import re
import argparse

parser = argparse.ArgumentParser(description="options")
parser.add_argument("-p", "--prefix", help="prefix for output files")
args = parser.parse_args()

assert re.match("^[a-zA-Z0-9_]+$", args.prefix), "non-alphanumeric characters found"

command = "my_external_program -t type -f %s -m 1 -M 1 -N 0 -H -p 16" % args.prefix
external_stacks_call = subprocess.Popen(command, shell=True, stdout=open(args.prefix + ".log.txt", "a"), stderr=open(args.prefix + ".log.txt", "a"))
external_stacks_call.wait()
问题如下:

  • 断言是否足够安全,以避免他人的伤害/问题,或其他意外问题?
  • 例如,有人输入前缀“stuff&&rm-rf/”
  • 在没有shell=True选项的情况下,不调用同一字符串的最佳方法是什么

  • 关于shell=True选项的危险性,以及shell=True的危险性,我已经在这里和其他地方看了几页,但是我没有找到一个很好的来源,来说明如何避免在外部程序中使用shell=True,因为它将逃逸空格,但是您也可以为命令行提供一个参数列表

    command = ["my_external_program", "-t", "type", "-f", str(args.prefix), 
               "-m", "1", "-M", "1", "-N", "0", "-H", "-p", "16"]
    
    这将允许模块正确、更安全地与外壳接口

    如果没有
    shell=True
    特殊字符将被转义,因此与原始命令相同的是

    $ my_external_program\ -t\ type\ -f
    
    等等


    这是一个优势,因为shell可以以相同的方式转义所有类型的特殊字符

    为什么要使用shell=True?@padraiccnningham如果没有它,命令将无法执行。。。这是我第一次尝试从pythoncall中调用外部程序。在命令上拆分并删除shell=True,然后使用.communicate()这样说是否正确。join(命令)基本上是在subprocess.popen(命令)上调用的?这将避免用户输入到外部命令字符串中的问题?@ded,no:
    subprocess.Popen(“.join(command),shell=True)
    不是
    subprocess.Popen(command,shell=False)
    的一般等价物。例如,前者将执行前缀为
    $(rm-rf/)
    的子命令,而后者将(正确且安全地)逐字传递字符串。同样,前者会让你接触到诸如shellshock之类的bug。使用
    shell=False
    是正确的选择,除非您有明确的、令人信服的理由,并且仔细考虑了安全问题。