如何正确清理文件名(防止shell注入)?

时间:2011-01-19 11:46:02

标签: python subprocess sanitization

在子进程(shell = False)中使用文件名之前,从外部源(例如:xml文件)清理文件名的常见做法是什么?

更新: 在发送一些解析后的字符串之前,我想做一些基本的安全检查。给定的示例在远程模式下使用mpg123(命令行audioplayer)来播放声音文件。

filename = child.find("filename").text # e.g.: filename = "sound.mp3"
pid = subprocess.Popen(["mpg123"],"-R"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
command = "L "+filename+"\n"  
pid.stdin.write(command.encode())

2 个答案:

答案 0 :(得分:3)

我可以想到几件事。

如果系统容忍,则可以进行轻量级验证。如果数据破坏或敏感数据泄露的可能性很小,也可能是合适的。您可以使用os.path.isfile测试以查看给定的字符串是否为实际文件。

更经典的“安全”编程设计可让您索引可播放的可接受文件,并根据用户输入进行查找。通过这种方式,您实际上永远不会传递用户输入。它通过查找已经验证的数据(已接受的可播放文件列表)进行“过滤”。

“消毒”输入是一种黑名单技术。它们总是不如白名单技术(上图)那么安全。如果您别无选择,只能“清理”数据,您必须了解数据如何通过您的系统以及您依赖的任何其他系统。然后,您必须制定规则以考虑所有系统中的任何缺陷或限制。您还必须涵盖经典的恶意输入案例,如数据输入大小,不可接受的字符编码等。

答案 1 :(得分:1)

除非您使用shell或执行任何操作,否则不需要对文件名进行清理。 Pythons open()不会执行给定文件名中的任何命令。

为了安全检查,为了避免覆盖文件,您使用操作系统的权限系统,并确保只运行程序的用户可以覆盖和访问它应该能够覆盖和访问的文件。

让任何从网络或其他进程获取输入的程序接受绝对路径名称通常不是一个好主意。在这种情况下,应该只允许在已定义的音乐文件夹下指定文件。我不认为mp3播放器会因为错误的文件而导致损坏,但至少可以让它崩溃,这会很烦人。