问题:
我在开发一个内部工具,允许用户上传图片,然后将这些图片显示给他们和其他人。
这是一个Java/Spring应用程序。我只需要关心IE11和Firefox v38+(Chrome v43+也可以)。
在开发完功能后,似乎用户可以创建一个文本文件,像这样:
<script>alert("malicious code here!")</script>
将其保存为"maliciousImage.jpg"并上传。
稍后,当该图像在图像标签内显示时:
<img src="blah?imgName=foobar" id="someImageID">
actualImage.jpg可以正常显示,而maliciousImage.jpg则显示为破碎的链接 - 最重要的是没有恶意内容被解释!
但是如果用户右键点击这个破碎的链接并点击“查看图片”...就会出现问题。
浏览器进行了“内容嗅探”,这对我来说是一个新概念,它检测到“maliciousImage.jpg”实际上是一个文本文件,并很好地将其呈现为HTML,没有任何犹豫。任何脚本标记都将传递给JavaScript解释器,正如您所想象的那样,我们不希望发生这种情况。
我到目前为止尝试过的方法
简而言之,我想到的防止浏览器进行内容嗅探的所有响应头组合。我在stack overflow等网站以及其他文档中找到的所有答案都暗示着设置content-type标题应该可以防止大多数浏览器对内容进行嗅探,并且设置X-content选项应该可以防止某些版本的IE。
我正在将x-content-type-options设置为no sniff,并设置响应内容类型。我阅读的文档使我相信,这应该停止内容嗅探。
response.setHeader("X-Content-Type-Options", "nosniff");
response.setContentType("image/jpg");
我正在拦截响应,这些标头存在,但似乎对恶意内容的处理没有影响...
我还试图在上传图片时检测哪些是恶意的和哪些不是,但我很快就发现这非常不容易...
最终目标:
自然而然地,任何输出都比在明文中执行文本文件作为HTML/javascript要好,但将任何恶意HTML显示为转义/CDATA的纯文本是理想的...虽然可能有些不切实际。
image.getContentType().equals(type)
等。 - adeneo