我一直认为HTTP Content-Type应该正确识别返回资源的内容。我最近注意到google.com上的一个资源,其文件名类似于/extern_chrome/799678fbd1a8a52d.js,其中包含HTTP标头:
HTTP/1.1 200 OK
Expires: Mon, 05 Sep 2011 00:00:00 GMT
Last-Modified: Mon, 07 Sep 2009 00:00:00 GMT
Content-Type: text/html; charset=UTF-8
Date: Tue, 07 Sep 2010 04:30:09 GMT
Server: gws
Cache-Control: private, x-gzip-ok=""
X-XSS-Protection: 1; mode=block
Content-Length: 19933
内容不是HTML,而是纯JavaScript。当我使用本地代理(Burp Suite)加载资源时,代理声明MIME类型是“script”。
是否有可接受的方法来确定从Web服务器返回的内容? Content-type标头似乎通常是正确的。扩展也是一个指标,但并不总是准确的。是检查文件内容的唯一准确方法吗?这是Web浏览器用来确定如何处理内容的吗?
答案 0 :(得分:1)
检查文件内容的唯一准确方法是什么?
它是浏览器用来确定文件类型的方法,但绝不准确。它不准确的事实是security关注的问题。
服务器可用于指示文件类型的唯一方法是通过Content-Type
HTTP标头。不幸的是,在过去,没有多少服务器为此标头设置正确的值。所以浏览器决定玩智能并尝试使用他们自己的专有算法来计算文件类型。
浏览器完成的“猜测工作”称为内容嗅探。理解内容嗅探的最佳资源是browser security handbook。另一个很好的资源是this paper,其建议现已纳入Google Chrome和IE8。
如何确定正确的文件类型?
如果您只是处理已知/小型服务器列表,只需要求他们设置正确的内容类型标头并使用它。但是,如果您正在处理您无法控制的野外网站,您可能需要开发某种内容嗅探算法。
答案 1 :(得分:1)
浏览器知道它是JavaScript,因为它通过<script src="...">
标记到达了它。
如果您将.js文件的URL键入URL的地址栏,那么即使服务器确实返回了正确的Content-Type,您的浏览器也不会将该文件视为要执行的JavaScript。 (相反,您可能会在浏览器窗口中看到.js源代码,或者提示将其保存为文件,具体取决于您的浏览器。)
浏览器不会对JavaScript执行任何操作,除非它由<script>
标记引用,简单明了。不需要内容嗅探。
答案 2 :(得分:0)
对于文本文件,例如JavaScript,CSS和HTML,浏览器将尝试解析该文件。如果在解析任何内容之前解析失败,则认为它完全无效。否则,尽可能保留和使用。对于JavaScript,它可能需要在语法上编译所有内容。
对于二进制文件,例如Flash,PNG,JPEG,WAVE文件,他们可以使用诸如magic library之类的库。魔术库使用文件的内容来确定文件的MIME类型,该文件实际上是唯一值得信赖的部分。
但是,不知何故,当您在浏览器中拖放文档时,在这种情况下,浏览器启发式检查是检查文件扩展名。真弱!因此,附加到POST的文件可能是.exe,您会认为它是.png,因为它是当前的文件扩展名...
我有一些代码来测试JavaScript中文件的MIME类型(拖放或浏览后):
https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/plugins/output/output.js
搜索MIME,您将找到执行该工作的各种功能。在编辑器中可以看到使用示例:
https://sourceforge.net/p/snapcpp/code/ci/master/tree/snapwebsites/plugins/editor/editor.js
可以在mimetype插件中找到基本MIME类型的扩展。
它是所有面向对象的代码,因此最初可能有点难以理解,但或多或少,许多调用都是异步的。
是否有可接受的方法来确定从Web服务器返回的内容? Content-type标头似乎通常是正确的。扩展也是一个指标,但并不总是准确的。
据我所知,Apache使用文件扩展名。假设您信任您的网站管理员而最终用户无法上传内容,实际上扩展程序非常安全。
检查文件内容的唯一准确方法是什么?
准确而安全,是的。话虽这么说,使用数据库系统的服务器可以将这样的元数据保存在数据库中,因此每次处理文件时都不必重新检查。此外,一旦检测到类型,它可以尝试加载以仔细检查MIME类型是否正确。这甚至可能发生在后端进程中,因此您不会浪费客户端的时间(实际上我的服务器会进一步检查每个文件是否也有病毒,因此即使是无法加载的文件也会以某种方式进行检查。)
这是Web浏览器用来确定如何处理内容的吗?
正如Joe White所提到的,在大多数情况下,浏览器需要来自文件的特定类型的数据:CSS的链接需要CSS数据;脚本需要JavaScript,Ruby,ASP;图像或图形标签需要图像;等
因此浏览器可以使用加载器来处理该类型的数据,如果加载失败,它就会知道它的类型不正确。因此浏览器实际上并不需要检测类型本身。但是,您必须相信当数据流无效时,加载器将正确失败。这就是为什么我们有Flash播放器的更新,以及更新GIF库的方式。
像魔术库一样,对类型的检测只会读取少数几个&#34;文件开头的字节数,并根据该类型确定类型。这并不意味着该文件有效且可以安全地加载。 GIF错误意味着该文件看起来非常像一个GIF图像(它具有正确的签名),但在某些时候,库中使用的缓冲区可能会溢出,可能会导致浏览器崩溃,并希望对黑客来说,接管你的电脑......