首页 > 代码库 > 深入解析跨站请求伪造漏洞:原理剖析
深入解析跨站请求伪造漏洞:原理剖析
当存心不良的Web站点导致用户的浏览器在可信的站点上进行非意愿的活动时,我们就说发生了跨站请求伪造(CSRF)攻击。这些攻击被誉为基于Web的漏洞中的“沉睡的巨人”,因为互联网上的许多站点对此毫无防备,同时还因为这类攻击一直为web开发和安全社区所忽视。
一、概述
当存心不良的Web站点导致用户的浏览器在可信的站点上进行非意愿的活动时,我们就说发生了跨站请求伪造(CSRF)攻击。跨站请求伪造攻击亦称跨站引用伪造(XSRF),会话叠置和混淆代理人攻击。我们之所以使用术语CSRF,是因为它是描述这类攻击时最常用的术语。这些攻击被誉为基于Web的漏洞中的“沉睡的巨人”,因为互联网上的许多站点对此毫无防备,同时还因为这类攻击一直为Web开发社区和安全社区所忽视。目前,人们尚未将CSRF攻击列入Web安全威胁分类中,学术和技术文献也鲜有述及CSRF攻击者。CSRF攻击易于识别、易于利用同时也易于修补。它们之所以存在,是由于Web开发人员对CSRF攻击的根源和严重性的无知所致。Web开发人员也可能还误认为对更有名的跨站脚本(XSS)攻击的防御措施同时也能防御CSRF攻击。
在本文的下篇中将向读者介绍本年度在一些大型站点上发现的几个严重的CSRF漏洞,这些漏洞允许攻击者采集用户的电子邮件地址,侵犯用户隐私并操控用户帐户。同时,我们还将介绍对服务器端的改造方案,以便使站点能够全面防御的CSRF攻击。该方案有多种优点,这得益于它们不使用服务器的状态,同时不妨碍典型的web浏览活动。此外,我们也介绍了一个客户端的浏览器插件,它可以保护用户免受某些类型CSRF攻击。服务器端保护措施能使站点本身具备完全防御CSRF攻击的能力,而客户端保护措施使用户未雨绸缪,提前采取防疫措施,以便在站点没有采取防护措施的情况下也能够免受CSRF攻击。尽管现在Web开发人员已经有了防御此类攻击的工具,但是仍希望大家能提高对CSRF攻击的防范意识。
二、跨站请求伪造攻击原理
为了便于读者对于跨站请求伪造漏洞的原理,下面我们用图例进行解释。图1、图2和图3为大家介绍了CSRF攻击的一般原理。
图1 浏览器和网站建立认证的会话 |
这里,Web浏览器已经跟可信的站点建立了一个经认证的会话。之后,只要是通过该Web浏览器这个认证的会话所发送的请求,都被视为可信的动作。
图2 浏览器发送有效的请求 |
上图中,浏览器正在发送一个有效的请求,即Web浏览器企图执行一个可信的动作。可信的站点经确认发现,该Web浏览器已通过认证,所以该动作将被执行。
图3 恶意站点伪造的有效请求 |
上图中,发生了一个CSRF攻击。发起攻击的站点致使浏览器向可信的站点发送一个请求。该可信的站点认为,来自该Web浏览器的请求都是经过认证的有效请求,所以执行这个“可信的动作”。CSRF攻击之所以会发生,其根本原因就是Web站点所验证的是Web浏览器而非用户本身。下面我们用一个具体的示例来详细介绍CSRF攻击。
假设某个站点存在CSRF攻击漏洞,比如一个基于Web的电子邮件网站,用户通过该站点可以发送和接收电子邮件。该站点利用隐式认证方式来验证用户身份,它的某个页面,如http://example.com/compose.htm包含一个供用户输入收信人的电子邮件地址、主题和消息的HTML表单,以及一个名为“Send Email”的按钮。
{formaction="http://example.com/send_email.htm"method="GET"}Recipient’s Email address: {input type="text" name="to"}Subject: {input type="text" name="subject"}Message: {textarea name="msg"}{/textarea}{input type="submit" value=http://www.mamicode.com/"Send Email"}{/form}
:当example.com站点的用户单击“Send Email”时,该用户输入的数据就会通过一个GET请求发送到http://example.com/send_email.htm。由于GET请求只是简单地将表单数据附加到URL上,所以用户发送的URL如下所示。这里假设该用户输入的收信人为“bob@example.com”,主题为“hello”,消息为“What’s your name?”:
http://example.com/send_email.htm?to=bob%40example.com&subject=hello&msg=What%27s+your+name%3F
注意的是,上面的URL的数据已经过编码,@被转换成%40,等等。
根据收到的数据向用户指定的收信人发送一封电子邮件。注意,send_email.htm所做的只是提取数据,随后用该数据完成一个动作。它并不理会该请求来自哪里,它唯一关心的是收到的请求。这意味着,即使上述URL是用户手动输入到他的浏览器的,那么example.com也照常发送一封电子邮件。例如,如果该用户在其浏览器地址栏中键入了下列三个URL,那么send_email.htm页面将三封电子邮件(分别发给Bob、Alice和Carol ):
http://example.com/send_email.htm?to=bob%40example.com&subject=hi+Bob&msg=testhttp://example.com/send_email.htm?to=alice%40example.com&subject=hi+Alice&msg=testhttp://example.com/send_email.htm?to=carol%40example.com&subject=hi+Carol&msg=test
这里会出现CSRF攻击,原因是send_email.htm会把收到的数据悉数提取,然后发电子邮件。它没有对自compose.htm页面的表单中的数据进行检验。因此,攻击者只要设法让用户向send_email.htm发送一个请求,那么send_email.htm这个页面就会引起example.com发送一封电子邮件,要紧的是,该邮件是以该用户名义发送的,并且包含的是攻击者任意选择的任何数据,这样攻击者就成功地进行了一次CSRF攻击。
为了利用这个弱点,攻击者需要强迫用户的浏览器向send_email.htm发送一个请求来完成一些邪恶的动作。我们假定用户浏览了一个为攻击者所控制的站点,并且目标站点没有采取针对CSRF攻击的防御措施。具体地说,攻击者需要伪造一个跨站请求,该请求的发源地是从他的站点,目的地为example.com,中间会路过受害者的浏览器。令人遗憾的是,HTML为制造这种请求提供了多种方式。例如,浏览器遇到标签时,任何被设置为src属性的URI都会被加载,即使那个URI不是一幅图像。攻击者可以用以下代码创建一个页面:
{img src=http://www.mamicode.com/"http://example.com/send_email.htm?to=mallory%40example.com&subject=Hi&msg=My+email+address+has+been+stolen"}
当用户访问这个页面时,一个请求被发送到send_email.htm,然后,将有一封来自该用户的电子邮件被发送给Mallory。这个例子跟后面将要介绍的纽约时报站点上发现的漏洞几乎完全一致。
要想成功发动CSRF攻击,攻击者只要能够引起用户的浏览器在另一个站点上执行一个非本意的动作即可,当然前提是用户必须有执行该动作的权限。CSRF攻击能获取跟用户一样大的权限,即任何用户可以执行的动作,攻击者利用CSRF攻击也能完成。所以,站点赋予用户的权限越大,受到CSRF攻击的可能性就越高,CSRF攻击带来的后果也越严重。
对于所有使用隐式的认证方式并且没有采取显式的针对CSRF攻击的自我保护措施的站点,CSRF攻击几乎总能得手。
三、跨站请求伪造漏洞的根本原因
CSRF攻击经常利用目标站点的身份验证机制,CSRF攻击这一弱点的根源在于Web的身份验证机制虽然可以向目标站点保证一个请求来自于某个用户的浏览器,但是却无法保证该请求的确是那个用户发出的或者是经过那个用户批准的。例如,假如Alice在浏览目标站点T,那么站点T便会给Alice的浏览器一个cookie,用于存放一个伪随机数作为会话标识符sid,以跟踪她的会话。该站点会要求Alice进行登录,当她输入有效的用户名和口令时,该站点会记录这样一个事实:Alice已经登录到会话sid。当Alice发送一个请求到站点T时,她的浏览器就会自动地发送包含sid的会话cookie。之后,站点T就会使用站点的会话记录来识别该会话是否来自Alice。
现在,我们假设Alice访问了一个恶意站点M,该站点提供的内容中的JavaScript代码或者图像标签会导致Alice的浏览器向站点T发送一个HTTP请求。由于该请求是发给站点T的,所以Alice的浏览器自动地给该请求附上与站点T对应的该会话cookie的sid。站点T看到该请求时,它就能通过该cookie的推断出:该请求来自Alice,所以站点T就会对Alice的帐户执行所请求的操作。这样,CSRF攻击就能得逞了。
其他大多数Web认证机制也面临同样的问题。例如,HTTP BasicAuth机制会要求Alice告诉浏览器她在站点T上的用户名和口令,于是浏览器将用户名和口令附加到之后发给站点T的请求中。当然,站点T也可能使用客户端SSL证书,但这也面临同样的问题,因为浏览器也会将证书附加到发给站点T的请求中。类似的,如果站点T通过IP地址来验证Alice的身份的话,照样面临CSRF攻击的威胁。
总之,只要身份认证是隐式进行的,就会存在CSRF攻击的危险,因为浏览器发出请求这一动作未必是受用户的指使。原则上,这种威胁可以通过对每个发送至该站点的请求都要求用户进行显式的、不可欺骗的动作(诸如重新输入用户名和口令)来消除,但实际上这会导致严重的易用性问题。大部分标准和广泛应用的认证机制都无法防止CSRF攻击,所以我们只好另外探求一个实用的解决方案。
四、CSRF攻击向量
成功发动攻击前提是,用户必须已经登录到目标站点,并且必须浏览了攻击者的站点或被攻击者部分控制的站点。如果一个服务器有CSRF漏洞,并且接受GET请求(就像上面的例子那样),那么无需使用JavaScript就可以发动CSRF攻击,例如,只需使用{IMG}标签就可以搞定。如果该服务器仅接受POST请求,那么要想从攻击者的站点自动发送POST请求到目标站点的话,就必须使用JavaScript。
五、CSRF与XSS
近来,跨站脚本攻击(XSS)漏洞引起了人们的广泛注意。XSS攻击通常是指,攻击者向一个站点注入恶意代码(通常为JavaScript),以攻击该站点的其它用户(即攻击的最终目标并非站点本身)。例如,站点可能允许用户发表评论,这样的话,评论由用户张贴,然后被存储在站点的数据库中,最后会展示给该站点的所有用户。如果攻击者能在评论中夹杂上恶意JavaScript代码的话,那么这些JavaScript代码就会嵌入到所有包含该评论的页面中。当一个用户访问该站点时,攻击者的JavaScript代码就被执行,执行权限具有目标站点一切特权。嵌入目标站点的恶意JavaScript代码将能发送和接收来自该站点上的任何页面的请求,并能够访问由该站点设置的cookie。要想防御XSS 攻击,站点必须仔细过滤所有的用户输入,以确保不被注入恶意代码。
CSRF和XSS攻击的区别在于,XSS攻击需要JavaScript,而CSRF攻击不需要;XSS攻击要求站点接受恶意代码,而对于CSRF攻击来说,恶意代码位于第三方站点上。过滤用户的输入可以防止恶意代码注入到某个站点,但是它无阻止法恶意代码在第三方站点上运行。由于恶意代码可以在第三方站点上运行,所以防御XSS攻击的措施无法保护站点不受CSRF攻击的危害。如果站点具有XSS攻击漏洞,那么它也有CSRF攻击漏洞。但是,即使站点针对XSS攻击采取了全面保护,却仍然面临CSRF攻击的威胁。
上面介绍了跨站请求伪造的原理、安全问题的根本原因、攻击手法和与跨站脚本攻击之间的区别,下面我们看看现有的安全策略是否能够防御这种攻击。
六、同源策略与跨站请求伪造
Web浏览器有一项艰巨的任务,那就是允许用户维护到达多个网站的安全的专用链接,同时还允许访问包含不可信代码的不可信的站点。另外,站点能够从不同的域加载资源。举例来说,站点a.com 能够分别使用{IMG}或者 {SCRIPT} 标签从b.com加载图象或者JavaScript。然而,如果用户已经登录到一个可信的站点,那么当然不应该让不可信的第三方站点读取可信的站点的内容。
为了能够在允许不可信的站点显示来自外部站点的数据的同时还能保持这些数据的私密性,人们创建了同源策略。该策略不仅定义了“源”的含义,还规定了当访问来自不同源的数据时,站点能做哪些事情。该策略认为,如果两个页面的协议、端口(如果给出的话)和主机完全一致,那么就说这两个页面是同源的。根据同源策略的规定,站点不能读取或者修改来自不同的源的资源。
然而,该策略却允许向不同源请求资源。因此,evil.com 可以在它的站点中通过{IMG}标签包含图像http://trusted.com/image.gif,但是它不能够读取这幅图像的像素。同样的,evil.com也可以在他的站点内利用{iframe}标签来包含http://trusted.com/private.htm ,但是evil.com却不能访问或者修改浏览器显示的这个页面的内容。
同源策略仅仅阻止了第三方站点读取来自其他站点的内容,但是却没有防止这些第三方站点向其他站点发出请求。因为CSRF攻击是由于某些请求被发出(而引起在服务器端执行了某些动作)所引起的,所以同源策略只能用来保护第三方站点上的数据的私密性,但是同源策略无法防止CSRF攻击。
七、跨域策略与跨站请求伪造
对于有些站点来说,进行跨域通信是非常有用的,有时候甚至的必不可少的。鉴于此,Adobe提出了一个机制,称为跨域策略,该策略在某些情况下可以允许它的Flash插件跟不同的域进行通信即发送和接收数据。该机制当前只用于Flash,具体地说,站点能够规定哪些第三方站点可以访问它。第三方站点只能跟其跨域策略文件中规定的第三方站点进行联络。下面的跨域策略文件允许访问源自www.friendlysite.com、*.trusted .com 和IP地址64.233.167.99的请求。这些文件被命名为crossdomain.xml并放在该域的根目录下。
{?xml version="1.0"?}{cross-domain-policy}domain="www.friendlysite.com" /}{allow-access-from domain="*.trusted.com" /}{allow-access-from domain="64.233.167.99" /}{/cross-domain-policy}
假设以上文件位于http://trusted.com/crossdomain.xml。如果evil.com使用Flash向http://trusted.com/private.htm发出了一个请求,Flash将首先加载http://trusted.com/crossdomain.xml以检验evil.com是否已作为受信任的域列于其中。因为它没有列于其中,所以该请求就会被阻止。相反,如果同一请求来自www.friendlysite.com的话,则Flash将允许该请求,这是因为www.friendlysite.com已经位于被许可的列表中了。
如果使用恰当的话,Adobe的跨域策略能够比同源策略(除非在crossdomain.xml中找到匹配,否则该请求无法启动)更好地防御CSRF攻击,并且具有更高的灵活性(如果目标站点信任发起方站点即源站点的话,则允许跨域通信)。 然而,跨域策略经常被不正确使用,比如将一个目标站点放到“accept all”的条款中,这会允许第三方从任何站点(不管这个站点是善意的还是恶意的)访问它。甚至Adobe的联盟站点crossdomainxml.org的crossdomain.xml文件也出现了不适当甚至极度危险的用法:域名crossdomainxml.org被注册到TPowerSDK Software 有限公司的heodore E Patrick名下,该公司在其LinkedIn profile(http://www.linkedin.com/in/tedpatrick)中写道他们是Adobe Systems的Flex的技术布道者。 这个站点提供了“accept all ”跨域策略文件的例子,使用该文件的危险性不言自明。
安全研究人员曾经对世界500强的网站进行了分析,其中发现有143个站点使用了crossdomain.xml策略文件。而在这143个站点中,又有47个站点对来自第三方站点的链接完全接受,这可能导致CSRF漏洞。Adobe的跨域策略可能是有效和安全的,但前提是要小心使用。如果在策略文件中使用了“accept all”的话,结果是非常严重的。
八、P3P与跨站请求伪造
Cookie可用于在站点之间跟踪用户,举例来说,如果登广告者在他的服务器上寄放了一张图片(即广告),而他的服务器将被大量广告发行站点所引用。当该图像被显示时,登广告者可以设置一个cookie,这样,当同一个用户访问不同的广告发布站点时,登广告者也能认出他是同一个人。换句话说,当该用户访问一个广告发布者的站点并加载登广告者的图像时,该用户的cookie会发回给登广告者,由于该cookie是唯一的,所以登广告者能够识别该用户。登广告者可以使用这些Cookie来收集有关该用户上网的习惯的数据。
Cookie在用户隐私方面的负面影响导致了“隐私权偏好选项平台” (Platform for Privacy Preferences,P3P)的出现。P3P“提供了通用的语法和传输机制,使得Web站点能够将网站对客户隐私的处理情况传达给Internet Explorer 6(或者其他任何用户代理)”。从Internet Explorer 6起,微软公司开始要求所有站点包含一个P3P策略,以便判断接受第三方Cookie。
按照微软公司的说法:
先进的cookie过滤技术,会对Web 站点的隐私做法进行评测,并根据站点的策略跟用户设置的比较结果来决定接受哪些Cookie。根据默认设置,用于收集个人标识信息的Cookie和不允许用户进行选择的Cookie被认为是“不能令人满意的”。默认时,将在浏览结束时把第一方中的不能令人满意的Cookie删掉,并拒绝第三方环境中不能令人满意的Cookie。(注意,P3P政策没有进行验证。所以如果一个站点要求具有一项可接受的政策,Internet Explorer就会允许第三方Cookie。)
假设一个用户正在浏览一个页面,而该页面包含了一张位于第三方站点上的图像。那么在P3P的环境中,虽然用户所在的页面被认为是安全的,但是第三方站点仍可能存在威胁。 对于CSRF漏洞来说情况正好相反,虽然第三方站点(是潜在的攻击目标)是安全的,但是用户所在的页面却存在潜在的危害。如果Internet Explorer认为一个第三方站点是危险的,那么它就会阻止向那个站点发送cookes。这样做能够在使用会话cookie的情况下有效地阻止CSRF攻击 ,因为Internet Explorer从跨站请求中提取验证信息。
Internet Explorer的P3P政策对CSRF漏洞的影响非常有趣:具有有效P3P政策的站点无法防范CSRF攻击(Internet Explorer认为这些站点是安全的,并且允许Cookie),而没有该政策的站点却能防御(Internet Explore认为这些站点是危险的,并拦阻Cookie)CSRF攻击。 注意,这些只对使用Cookie进行认证的受CSRF漏洞影响的站点有效。使用其它的类型的认证的站点可能仍然对CSRF攻击有脆弱性。
总而言之,当使用会话cookie进行认证并且目标站点没有实现P3P政策的时候,Internet Explorer使用P3P能够让用户的IE免受CSRF攻击。这项保护措施是P3P政策的无心插柳之作,因为它的本意并非防止CSRF攻击。所以,站点应该实现我们的建议的服务器端保护措施,具体如本文下篇所述。
九、小结
本文我们对跨站请求伪造攻击的原理做了深入分析,并指出了该漏洞的根本原因所在;同时介绍了该漏洞的攻击向量,以及它与跨站脚本攻击之间的关系。之后后,说明了现有的安全模型,如同源策略等是无法防御该漏洞的。最后,说明了P3P对于跨站请求伪造的作用。
在下篇中,我们将向读者介绍在一些大型站点上发现的几个严重的CSRF漏洞,攻击者利用这些漏洞不仅能够采集用户的电子邮件地址,侵犯用户隐私并操控用户帐户。实际上,如果金融站点出现了跨站请求伪造漏洞的话,这些漏洞甚至允许攻击者从用户的银行帐户中划走资金。为了全面的防御CSRF攻击,建议对服务器端进行改造。此外,我们还会介绍服务器端解决方案应具备的特征,如果缺乏这些特性,就会导致CSRF保护措施不必要地妨碍典型的web浏览活动。除此之外,我们还将介绍一个客户端浏览器插件,有了该插件的保护,即使站点自身没有保护措施的情况下,用户也能免受某些类型的CSRF攻击的滋扰。跨站请求伪造是一种严重的Web漏洞,希望大家能提高对CSRF攻击的防范意识。
深入解析跨站请求伪造漏洞:原理剖析