基于IE的MIME sniffing功能的跨站点脚本攻击

IE有一个特性,那就是在将一个文件展示给用户之前会首先检查文件的类型,这乍看起来并没什么问题,但实际上这是相当危险的,因为这会允许IE执行图片中的代码,即嵌入在一个图像中的JavaScript代码。引入MIME sniffing功能的初衷是用来弥补Web服务器响应一个图像请求时有可能返回错误的内容类型信息这一缺陷。

  但是事不遂人愿,心怀不轨的人可以轻易滥用这一特性,如通过精心制作一个图像文件,并在其中嵌入可以被浏览器所展示和执行的HTML和JavaScript代码。本文将深入考察该问题,并为用户和网站开发人员介绍如何降低此问题带来的风险。 
  一、危险的MIME sniffing功能 
  对于Web 2.0应用程序来说,允许用户上载图像是一项基本的要求。但是,IE用户面对这些图片时却要小心了,因为IE的某些功能会为利用图片进行跨站点脚本攻击大开方便之门。 
  虽然许多大型站点都设法保护其访问者免受可能的JavaScript攻击,例如实现专门用于防御活动内容的过滤器等,但是他们却无法跟活动内容一刀两断,因为对于个人简介、博客和论坛来说,JavaScript、HTML 代码和Flash小应用程序是不可或缺的活动内容。 
  此外,大部分交互型站点都允许用户上载和链接他们的图片,但是攻击者却可以利用此功能来颠覆IE为保证兼容性和提供额外的安全性而引入的某些功能。攻击者只需在图像的开头部分嵌入一些HTML代码和JavaScript,那么当IE打开这个做过手脚的图像时,浏览器所做的不是显示图像,而是检测并运行图像中嵌入的代码。 
  之所以出现这种情况,是因为浏览器可以用来确定文件类型的方式多种多样,例如文件扩展名jpg可以指出一个图像为JPEG格式,此外Web服务器还可以在HTTP报头中定义Content-Type(在本例中为image/jpg),但是一般说来使用上载的文件的文件名扩展部分来指出文件的类型。 
  最后,大多数 Web 浏览器还会检查一个文件的开始几个字节(即通常所说的文件的“签名”),这几个字节通常为一些众所周知的字节序列,例如PNG、PK、JPEG、JFIF等等。 
  迄今为止,我们介绍了浏览器可以确定文件内容类型的三种方法,即通过文件本身的扩展名或文件开头部分的签名,或通过服务器响应报头Content-Type来确定文件类型。 
  不过,后来IE4引入了第四种方法,即通常所说的MIME sniffing或者MIME类型检测方法。所以,现在的IE版本都不自动地假定来自web的文件的内容类型就是服务器在HTTP报头中的所声明的内容类型。IE浏览器既不信任文件名扩展部分,也不信任签名,相反,它是通过检查文件开头的256字节内容来确定文件的类型。 
  然而,只有当用户直接调用URL下载文件时IE才这样做。当使用IE打开HTML中的图像标签(IMG)所连接的本地存储的文件或者图像的时候,则不会进行嗅探。 
  IE引入MIME sniffing功能的初衷是用来提防服务器给出的错误内容类型指示的,但是攻击者却利用它来规避IE中的安全防御功能,即防止浏览器自动地执行所下载的文件(如hta文件)的那些功能。 
  此外,MIME sniffing还使得浏览器能够容忍在Content-Type声明中的偶然性错误,例如,如果服务器声明某文件类型为text/plain文件,然而实际提供的却是一个HTML文件,那么IE将它作为HTML处理。 
  对于常见的GIF、JPEG和PNG格式,只要文件扩展名、Content-Type和签名所指的类型相一致,那么浏览器就会对MIME sniffing所得到的结果置之不理。只有当文件扩展名、Content-Type和签名所指的类型有出入时,IE才会以MIME sniffing所确定的结果为准。 
  二、倒打一耙的MIME sniffing功能 
  现在,如何保护用户免受恶意服务器的侵害与如何为不正确地配置服务器的管理员提供有效帮助已经成为Web 2.0所面临的一大问题。 如果文件的扩展名、Content-Type和签名相抵触,那么浏览器会以内容为准。 
  所以,如果一幅图片的开头部分为一些HTML代码的话,虽然乍一看好像是无害的,但是实际上却可能相当危险,因为IE会执行图片中的代码。这为攻击者把JavaScript嵌入图像提高了一个机会,所以他们可以利用这种方式执行跨站点脚本攻击,使用精心制作的图像来窃取受害者在当前访问的服务器上的身份验证cookie,然后以受害者的身份登录到那个服务器。 
  三、援兵未至 
  微软公司已经认识到这个问题,并计划IE的新版本中加以修复。IE8不再探测图像,因此,它会忽略嵌入的HTML。此外,对于特定的下载,还可以通过为私有的Content-Type以及authoritative指定值来关掉MIME sniffing功能,例如content-type=text/html; authoritative=true;。然后,IE会把文件当作服务器指出的类型来处理。 
  关键情况下,可以使用新的“X-Download-Options: noopen”头部来确保在站点上下文的外部显示相应的文件,这意味着即使HTML文件也能够安全的投递,因为浏览器只是将文件保存起来而已。遗憾的是,IE8要想全面替代其他版本的IE尚需时日,在此之前,Web站点对此还是指望不上的。 
  四、急救措施 
  实际上,如今想要抵挡这些精心制作的文件也并非难事。自Windows XP SP2以来,用户已能禁用IE中的MIME sniffing功能,方法是打开浏览器的“工具”菜单中选择“Internet 选项”,点击“安全”选项卡,在“请为不同的区域的Web内容指定安全设置(z)”下面选择“Internet”图标,在“该区域的安全级别(L)”下面点击“自定义级别”按钮,最后启用“基于内容打开文件,而不是文件扩展名”选项即可。然而,这样做会重新开放一些以前的古老漏洞! 
  这是否能够提供安全性只能够靠实践来证明。我们的重点不应该放在在用户间推广这个技巧,而是应该设法让web服务应用提供安全保障措施来保护访问者,并确保Web服务提供方的系统不向用户传送精心制作的图像。 
  管理员可以使用脚本检查上传到其服务器中的文件的类型的一致性。举例来说,如果某图像的文件名扩展部分为.jpg,并且文件起始字节部分的签名也指出是相同的类型(在Linux下可以使用file image.jpg命令,而在PHP中可以使用getimagesize加以印证),经过上述验证后,服务器才能发出该文件。 
  这样,即使文件包含HTML 代码,IE也不会执行这些代码。然而要注意的是,通过这种方式只能保护图像的安全,同时服务器声明的Content-Type必须完全正确才行。 这个方法对其它格式均不起作用。 
  然而,要想达到绝对的可靠性,需要检查文件的前256字节是否HTML 代码。IE使用常见的< body >、< head >、< html >、< img >、< script >等等标签来识别HTML代码。如果在文件的前256字节中没有发现任何标签的话,微软的浏览器就无法解释该文件了。 
  管理员也可以这样配置服务器,当文件被下载(而非打开)时,服务器总是发出头部“Content-disposition: attachment; filename="< filename.ext >”。 这样就能防止浏览器在该站点的上下文中打开此文件,而是使用本地链接的应用程序来打开此文件,但是这样做会使用户感觉很不爽。 遗憾的是,这种头部重写技术只对那些不允许直接访问文件的用户有效。 
  鉴于此,所上传的文件的存储位置不应该位于可公开访问的地方,并且最好为文件随机命名。 
  实际上,最有效的方法是使用ImageMagick或者类似的工具来转换图像文件的格式。这能从图像中清除掉所有代码段,从而彻底摆脱这些代码为用户带来的威胁。 
  像Facebook和Twitter这样的大型站点会对用户上传的肖像照片进行转换,但是必须小心行事,因为这有可能打开另一个攻击方式。例如,如果某人在ImageMagick中发现了一个缓冲区溢出问题,那么攻击者可能进行一番尝试,并找到一种利用特制的相片来利用该问题的方法。 
  五、总结 
  MIME sniffing功能本是IE的忠诚卫士,谁知他如今突然“倒戈”,助纣为虐来危害IE用户。对策当然是有,但是这些对策是否靠谱却是个悬而未解决的问题。目前,通过图像发动的跨站点脚本攻击看起来还不太常见,但是世界正在发生急剧的改变:交互型网站正在变成犯罪的首选目标。 
  好在,我们还可以使用其它的浏览器,例如Firefox等,这倒不失为一个补救措施。当然Firefox也进行MIME sniffing,但是它却不会莫名其妙地将图像作为HTML进行解释

MIME sniffing攻击的更多相关文章

  1. MIME Sniffing

    Abstract: The web.config file does not include the required header to mitigate MIME sniffing attacks ...

  2. header的安全配置指南

    0x00 背景 在统计了Alexa top 100万网站的header安全分析之后(2012年11月 - 2013年3月 - 2013年11月),我们发现其实如何正确的设置一个header并不是一件容 ...

  3. xmlhttp

    File an issue about the selected textFile an issue about the selected text XMLHttpRequest Living Sta ...

  4. Awesome Go精选的Go框架,库和软件的精选清单.A curated list of awesome Go frameworks, libraries and software

    Awesome Go      financial support to Awesome Go A curated list of awesome Go frameworks, libraries a ...

  5. What are all the possible values for HTTP “Content-Type” header?

    What are all the possible values for HTTP “Content-Type” header? You can find every content type her ...

  6. 你的图片可能是这样被CORB“拦截”的

    问题 最近学习一个uniapp+nodejs的项目,前端写了这样一个标签 <image :src="info.imgUrl" ></image> 按理说不应 ...

  7. XSS(跨站脚本攻击)的最全总结

    从OWASP的官网意译过来,加上自己的理解,算是比较全面的介绍.有兴趣的可私下交流. XSS 跨站脚本攻击 ============================================== ...

  8. PHP程序的常见漏洞攻击分析

    综述:PHP程序也不是固若金汤,随着PHP的广泛运用,一些黑客们也在无时不想找PHP的麻烦,通过PHP程序漏洞进行攻击就是其中一种.在节,我们将从全局变量,远程文件,文件上载,库文件,Session文 ...

  9. kali 密码攻击

    第八章 密码攻击 作者:Willie L. Pritchett, David De Smet 译者:飞龙 协议:CC BY-NC-SA 4.0 这一章中,我们要探索一些攻击密码来获得用户账户的方式.密 ...

随机推荐

  1. C# 公共类

    https://github.com/Jimmey-Jiang/Common.Utility/tree/master/Utility%E5%9F%BA%E7%A1%80%E7%B1%BB%E5%A4% ...

  2. Python 画3D图像

    绘制一副3D图像 draw3D(X,Y,Z, angle) import numpy as np from matplotlib import pyplot as plt from mpl_toolk ...

  3. jQuery实现评论弹幕、弹幕漂浮、滚动代码

    1.html代码和jquery代码: <!DOCTYPE html> <html> <head lang="en"> <meta char ...

  4. Solr——从postgresql数据库导入数据

    1,配置准备 本文的前提是你已经配置好了solr,并新创建了一个core,我们下面都会按照前一篇文章中的core_demo为基础开始 2,修改soreconfig.xml 在soreconfig.xm ...

  5. Solr——Windows下部署Solr6.6.0至Tomcat8.5.28(一)

    一.window 环境 solr 6.6.3 下载地址 http://archive.apache.org/dist/lucene/solr/ jdk 1.8    tomcat 8.5 本机tomc ...

  6. MySQL/InnoDB中,对于锁的认识

    MySQL/InnoDB的加锁,一直是一个面试中常问的话题.例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?我在工作过程中,也会经常用到,乐观锁,排它锁,等.于是今天就对 ...

  7. 剑指offer(一):二维数组中的查找

    说明: 1.本系列是根据<剑指Offer>这个系列做的一个小笔记. 2.直接动力是因为师兄师姐找工作很难,而且机械出生的我面试算法更难. 3.刚开始准备刷LeetCode.LintCode ...

  8. django之模板系统 --》内容(filter过滤器、tags标签【for、if、with】、母板以及继承、crf_token、注释、组件、静态文件【load static】、get_static_prefix、自定义标签和tag)

    常用: Django模板中只需要记两种特殊符号: {{ }}和 {% %} {{ }}表示变量,在模板渲染的时候替换成值,{% %}表示逻辑相关的操作. 变量 {{ 变量名 }} 变量名由字母数字和下 ...

  9. ROS学习手记 - 8 编写ROS的Publisher and Subscriber

    上一节我们完成了 message & srv 文件的创建和加入编译,这次我们要玩简单的Publisher 和 Subscriber 要玩 Publisher 和 Subscriber, 需要具 ...

  10. 35. Oracle监听器启动出错:本地计算机上的OracleOraDb11g_home1TNSListener服务启动后又停止了解决方案

    一.原因分析 你安装oracle的时候是连网的,那么listener.ora文件里的HOST=网络给你分配的IP地址,而在你断网的时候就会出现这样的情况. 三.解决办法 方法一:监听器 通过liste ...