0

我有一个应用程序,用户应该能够上传各种各样的文件,但我需要知道每个文件是否可以安全地将其文本表示形式显示为纯文本。

像使用python-magic

m = Magic(mime=True).from_buffer(cgi.FieldStorage.file.read())

给了我正确的 MIME 类型。

但有时,脚本的 MIME 类型是application/*,因此仅查找m.startswith('text/')是不够的。

另一个网站建议使用

m = Magic().from_buffer(cgi.FieldStorage.file.read())

并检查'text' in m.

第二种方法对于任意文件上传的集合是否足够可靠,或者有人可以给我另一个想法吗?

非常感谢。

4

2 回答 2

1

你的目标是什么?你想要真正的哑剧类型吗?出于安全原因,这很重要吗?还是“很高兴拥有”?

问题是同一个文件可以有不同的 mime 类型。当脚本文件有合适的#!头时,python-magic 可以确定脚本类型并告诉你。如果标题丢失,text/plain可能是你能得到的最好的。

这意味着没有通用的“将始终有效”的神奇解决方案(尽管模块的名称)。您将不得不坐下来思考您可以获得哪些信息,它意味着什么以及您希望如何处理它。

安全的解决方案是创建一个您接受的 mime 类型列表并检查它们:

allowed_mime_types = [ ... ]
if m in allowed_mime_types:

这意味着只接受完美匹配。这也意味着您的服务器将出于某种原因拒绝没有正确 mime 类型的有效文件(缺少标题,魔术无法识别文件,您忘记在列表中提及 mime 类型)。

或者换一种说法:如果你真的不在乎,为什么还要检查文件的 mime 类型?

[编辑]当你说

我需要知道每个文件是否可以安全地将其文本表示形式显示为纯文本。

那么这并不像听起来那么容易。首先,“文本”文件中没有存储编码,因此您需要知道用户在创建文件时使用的编码。这不是一项微不足道的任务。有一些启发式方法可以这样做,但是当使用 ISO 8859-1 和 8859-15 之类的编码(后者有欧元符号)时,事情会变得很棘手。

要解决此问题,您需要强制用户以特定编码保存文本文件(UTF-8目前是最佳选择),或者您需要提供用户必须将文本粘贴到其中的表单。

使用表单时,用户可以查看文本是否正确编码(他们在屏幕上看到),他们可以解决任何问题,并且您可以确保浏览器向您发送使用 UTF-8 编码的文本。

如果你不能这样做,你唯一的选择是检查输入中 0x20 以下的任何字节,除了\r,\n\t. 这是对“这是一个文本文档”的一个很好的检查。

但是当用户使用变音符号时(比如当你编写一个在世界范围内使用的应用程序时),这种方法最终会失败,除非你可以在用户端强制执行特定的编码(你可能不能这样做,因为你不信任用户)。

[EDIT2]因为你需要这个来检查实际的源代码:如果你想确保源代码是“安全的”,那么就解析它。大多数语言允许在不实际执行的情况下解析代码。这会给你一些真实的信息(因为解析器知道要寻找什么)并且你不需要做出疯狂的猜测:-)

于 2012-08-14T07:52:58.387 回答
0

玩了一会儿,我发现我可以正常使用Magic(mime_encoding=True)结果!

我在我的 Dropbox 文件夹上运行了一个简单的脚本,并通过编码和扩展名对结果进行分组,以检查是否存在违规行为。

但通过寻找'binary' in encoding.

我想我会坚持下去,但谢谢大家。

于 2012-08-14T08:01:45.730 回答