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

6 投票
2 回答
6288 浏览
提问于 2025-04-16 10:14

在使用外部来源(比如: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())

2 个回答

3

我想到了一些事情。

如果系统比较宽容,可以进行一些简单的验证。如果数据被破坏或者敏感数据泄露的可能性很小,这样做也是合适的。你可以通过使用 os.path.isfile 来测试你给的字符串是否真的是一个文件。

一种更经典的“安全”编程设计是先列出可以播放的文件,然后根据用户输入进行查找。这样你就不会直接传递用户的输入,而是通过查找已经验证过的数据(即可播放文件的列表)来“过滤”用户的输入。

对输入进行“清理”是一种黑名单技术。这种方法的安全性总是低于白名单技术(上面提到的)。如果你不得不“清理”数据,你需要了解这些数据是如何在你的系统以及你依赖的其他系统中流动的。然后你需要制定规则,考虑到所有系统中的缺陷或限制。你还需要处理一些经典的恶意输入情况,比如数据输入大小、不可接受的字符编码等等。

1

文件名不需要特别处理,除非你在使用命令行或者执行其他操作。Python的open()函数不会执行文件名中的任何命令。

为了安全起见,避免覆盖文件,你可以使用操作系统的权限系统,确保运行程序的用户只能覆盖和访问他们应该能操作的文件。

一般来说,不建议让任何从网络或其他进程接收输入的程序接受绝对路径名。在这种情况下,应该只允许指定在一个特定的音乐文件夹下的文件。我觉得给mp3播放器错误的文件不会造成严重损害,但至少可能会让它崩溃,那样就很烦人了。

撰写回答