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

Posted

技术标签:

【中文标题】如何正确清理文件名(防止外壳注入)?【英文标题】:How to properly sanitize a filename (protect against shell injection)? 【发布时间】:2011-06-11 17:07:57 【问题描述】:

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

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

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())

【问题讨论】:

如果不涉及 shell,为什么要清理文件名? 为了避免覆盖或读取系统/私有文件? 消毒什么?您需要提供更多详细信息。 无论你做什么,从import oshelp(os.path)开始 这个问题的答案可能会有所帮助:***.com/questions/295135/… 【参考方案1】:

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

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

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

【讨论】:

通常是我们认为不会造成损害的程序。当然,我认为在这种特殊情况下,如果有的话,它可能会相当小。 @dietbuddha:当然,这就是为什么将其限制到特定目录很重要。并且不以root身份运行它等,但这是另一个问题。 :)【参考方案2】:

我能想到几件事。

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

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

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

【讨论】:

以上是关于如何正确清理文件名(防止外壳注入)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 中清理(防止 SQL 注入)动态 SQL?

清理请求以防止 SQL 注入攻击

PHP 清理数据以防止SQL注入攻击

如何防止 XML 注入

PHP 代码注入 - 这怎么会发生以及如何防止它?

如何正确清理 docker devicemapper 文件夹?