我有一个应用程序,用户应该可以上传各种文件,但我需要知道每个文件,我是否可以安全地将其文本表示显示为纯文本。
使用python-magic之类的
m = Magic(mime=True).from_buffer(cgi.FieldStorage.file.read())
为我提供了正确的MIME类型。
但有时,脚本的MIME类型为application/*
,因此仅仅查找m.startswith('text/')
是不够的。
Another site建议使用
m = Magic().from_buffer(cgi.FieldStorage.file.read())
并检查'text' in m
。
第二种方法对于任意文件上传的集合是否足够可靠,或者有人可以给我另一个想法?
非常感谢。
答案 0 :(得分: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
除外。这是一个非常好的检查“这是一个文本文档”。
但是当用户使用变音符号时(比如当你编写一个全世界都在使用的应用程序时),这种方法最终会失败,除非你可以在用户一侧执行特定的编码(你可能不会这样做) t信任用户)。
[EDIT2] 因为你需要这个来检查实际的源代码:如果你想确保源代码是“安全的”,那么解析它。大多数语言允许解析代码而不实际执行它。这会给你一些真实的信息(因为解析器知道要查找什么),你不需要做出疯狂的猜测: - )
答案 1 :(得分:0)
在玩了一下后,我发现我可以使用Magic(mime_encoding=True)
结果!
我在Dropbox文件夹上运行simple script,并按编码和扩展程序对结果进行分组,以检查是否存在违规行为。
但通过寻找'binary' in encoding
确实看起来很有用。
我想我会坚持下去,但谢谢大家。