我只是希望能够上传 .txt 或 .csv 文件。
听起来很简单,不是吗?它不是。然后是一些。
简单的方法是在将文件存储到文件系统之前测试文件是否以“.txt”或“.csv”结尾。在您让用户提交的文件名靠近文件系统的任何位置之前,这应该是对文件名允许包含的内容进行更深入验证的一部分。
由于在某些平台(尤其是 Windows)上,文件名中可以包含哪些内容的规则很复杂,因此通常最好使用已知良好的名称和扩展名独立创建自己的文件名。
在任何情况下,都不能保证浏览器会向您发送一个具有可用名称的文件,即使确实如此,也不能保证该名称的末尾会包含“.txt”或“.csv” ,即使它是文本或 CSV 文件。 (有些平台根本不使用扩展名来输入文件。)
虽然您可以尝试嗅探文件的内容以查看它可能是什么类型,但这非常不可靠。例如:
<html>,<body>,</body>,</html>
可以是纯文本、CSV、HTML、XML 或各种其他格式。最好让用户明确控制他们正在上传的文件类型(或为每种类型使用一个文件上传字段)。
现在这才是真正令人讨厌的地方。假设您已接受上传并将其存储为 /data/mygoodfilename.txt,并且 Web 服务器正确地将其作为 Content-Type 'text/plain' 提供。您认为浏览器将其解释为什么?纯文本?你应该很幸运。
问题在于浏览器(主要是 IE)不信任您的 Content-Type 标头,而是嗅探文件的内容以查看它是否看起来像其他东西。将上面的 sn-p 作为纯文本提供,IE 会很乐意将其视为 HTML。这可能是一个大问题,因为 HTML 可以包含客户端脚本,这些脚本将接管用户对站点的访问(跨站点脚本攻击)。
此时,您可能会想在服务器端嗅探文件,例如使用“文件”命令来检查它不包含“”。但这注定要失败。 “file”命令不会像 IE 那样嗅探所有相同的 HTML 标签,并且其他浏览器无论如何都会以不同的方式嗅探。准备一个“文件”声称不是 HTML 的文件很容易,但 IE 仍会将其视为 HTML 文件(具有安全灾难隐患)。
诸如“文件”之类的内容嗅探方法只会给您一种虚假的安全感。这是一种用于松散猜测文件类型的便捷工具,不是一种有效的工具安全措施。
此时你最后绝望的可能性是: