|
|
|
|
移动端

如何识别和预防跨站请求伪造攻击

作为开发者,您可以通过本文了解到如何通过处理HTTP请求和cookies,来保障您的Web应用安全,并防止CSRF(跨站请求伪造)攻击。

作者:陈峻编译来源:51CTO|2018-01-16 11:30

人工智能+区块链的发展趋势及应用调研报告


【51CTO.com快译】在您浏览某个网站时,该网站经常会以您的名义向另一个网站请求各种数据。例如,在大多数情况下,某个网站上所显示的视频一般不会存储在网站本地。而该视频之所以可以出现在该网站上,是因为它实际上是从诸如youtube.com之类的视频流媒体网站嵌入过来的。

这就是所谓的内容分发网络(CDN),它能用于更快速度地交付各种内容与作业。通常许多网站都会将脚本、图像和其他带宽密集型的资源存放在CDN上,因此当您浏览图像和脚本文件时,它们会从最近的CDN资源进行下载,而并非来自网站本身。

虽然上述方法对于用户良好的浏览体验是必需的,但是它们也可能会成为各种安全问题的源头。因为您正在浏览的网站能够通过请求浏览器,在未经您同意的情况下从另一个网站上获取数据。而如果此类的请求并未正确处理的话,攻击者就可以发动跨站请求伪造攻击。

跨站请求的危害

当一个网站以您的名义向另一个网站请求数据时,只要请求无需认证,例如并未发送会话cookie,那么就不存在安全问题。然而当用户的会话cookie连同请求一并被发送时,攻击者就能发动跨站请求伪造攻击,进而滥用受攻击浏览器与Web服务器之间的信任关系。

在本文中,我们将重点讨论浏览器行为所引发的危险,以及攻击者是如何利用这个“优势”,来发动跨站请求伪造攻击的。为了理解跨站请求伪造的工作原理,让我们首先对HTTP请求和cookies做一个简单的介绍。

一、HTTP请求和Web Cookies的简要介绍

1.HTTP的GET和POST请求

HTTP GET请求

HTTP GET请求是您对一个Web服务器数据的请求。例如,当您在Web浏览器中输入网址(URL)时,就是指示浏览器发送一个HTTP GET请求到该网站所对应的Web服务器上。相应地,该Web服务器也会发送响应回到浏览器端。

HTTP POST请求

HTTP POST请求是指您发送那些要在Web应用中发布的数据。例如:当您提交Web表单时,如果这是一个登录或交互的表单,那么您的浏览器就会产生一个HTTP POST请求。该HTTP POST请求包含着您通过Web表单所提交的数据。

2.自动生成HTTP GET和POST请求

有时候GET和POST请求能通过某些HTML标签,或者一段JavaScript代码来自动触发。因此,它们并非总是需要与用户交互的。例如:在src属性中被声明为图像链接的<img>标签,就会自动生成一个GET请求。另一个例子则是XHR POST请求,它在用户输入查询时,被用于自动获取各种下拉式的搜索提示。

3.网站与会话Cookie

一般网站使用cookies来识别用户,或是在网站上保留用户的登录会话。会话cookie通常包含着唯一的ID,Web应用程序将用它作为标识号,以判定那些已经完成登录了的特殊用户。因此,当一个cookie被设置用于某个特定网站时,浏览器就会将它连同每一个发往该网站的HTTP请求,都保留在已登录的会话中。然而,这并非只关乎到会话cookie本身的问题。通过使用CSRF,就算Web服务器能够根据IP地址予以识别,攻击者仍然能够以用户的身份,使用NTLM或Basic Auth的认证方式来发送各种请求。

二、跨站请求伪造的工作原理

由于跨站点请求不需要您的批准,攻击者就可以滥用它,并且在未经您的同意和知晓的情况下,发送各种请求。下面是一个典型场景,让我们看看这个问题是如果被暴露出来的。

Web表单的简介

short_introduction_to_web_forms

我们来试想一个能够允许您去修改电子邮件地址的网站。您所要做的就是:在您登录之后,将您新的地址写入上述的字段,并点击“更改”。而如果您还没有登录,也就是说,在您并没有会话cookie的时候,该表单是不会工作的。下面让我们来看看底层的HTML代码是如何让这个输入字段工作的:

  1. <body>  
  2. <p>Your new email address</p>  
  3. <form method = "POST" action = "mail.php">  
  4. <input type = "text" name = "email" placeholder = "Change your email address">  
  5. <button type = "submit">change</button>  
  6. </form>  
  7. </body> 

在上述Web表单代码中,有三个重要的HTML属性:method、action和name。

Method属性

HTML的method属性是用来指定要用到的HTTP动作,并且在默认情况下,就是GET。当使用GET时,所有的参数值会被作为URL请求的一部分发送出去,因此在浏览器地址栏上,它们会在问号字符之后显示出来,如下所示:

https://www.example.com/mail.php?email=alice@example.com

这些请求会被记录到Web服务器的日志文件,以及浏览器的历史记录中。因此,GET动作只能用于传输一些非敏感的信息,以及不做任何数据修改的操作(包括:插入、更新、删除等)。比如:表示您正在浏览的当前页面:?page=home。

HTTP的POST动作经常被用在各种典型的Web表单里,因为它将数据作为请求的主体进行发送。因此,在服务器日志或浏览器历史记录中并无发送数据的记录。这就很适合于传输诸如密码这类的敏感和大量的数据。

Action属性

HTML的第二个属性是action,它指定了请求的目标。目标可以是网站内部或外部、甚至是在另一个域中的页面。在上面的代码示例中,该值为mail.php,这是一个PHP脚本,可让您改变电子邮件地址的名称。

Name属性

name属性是在Web表单的输入域中。它所包含的参数名称被用来存放您所提交的数据。因此,如果您输入alice@example.com,并点击提交按钮。那么mail的参数值将被设置为alice@example.com,同时Web服务器将收到如下的参数映射值:

mail=alice@example.com

HTTP POST请求

一旦您提交了该表单,浏览器就会发送下面的HTTP请求:

  1. POST /email.php HTTP/1.1mail=alice@example.com  
  2. Host: example.com  
  3. Cookie: SESSION=e29a31e41c9512a4bd  
  4. Content-Type: application/x-www-form-urlencoded  
  5. mail=alice@example.com 

如您所见,Host的HTTP头里包含了从表单提交过来的网站主机名。另外它还包括了会话cookie,Web应用可以籍此来确定您是否已经登录过。

三、在Web表单中的跨站请求伪造攻击

创建一个Web表单的副本

上面所涉及的知识会很容易让人联想到:攻击者将您的邮件地址更改成任何他想要的信息。他可以去复制Web表单,并放置到自己的Web服务器上,例如:http://www.attacker.com/evil.php。下面就是新表单的示例:

  1. <form id = "csrf_form" method = "POST" action = "http://example.com/email.php">  
  2. <input type = "text" name = "mail" value = "bob@attacker.com">  
  3. <form>  
  4. <script>  
  5. document.getElementById('csrf_form').submit();  
  6. </script> 

从上述代码您也许能注意到:该表单并没有提交按钮,因此攻击者可以在未经您同意或知晓的情况下触发该Web表单。此处应该有的按钮被替换成了一行JavaScript,如下所示:

document.getElementById('csrf_form').submit();

这段JavaScript代码先选取表单里的元素,然后以JavaScript的形式进行提交。随着提交的发生,受害者的电子邮件地址随即被更改成了bob@example.com,而在上述代码中属性值正是这个值。

攻击者的HTTP请求

以下是由此类攻击所产生的HTTP POST请求。为了便于阅读,我们在此删掉了那些不相关的请求头部信息:

  1. POST /email.php HTTP/1.1  
  2. Host: example.com  
  3. Origin: http://attacker.com  
  4. Referer: http://attacker.com/csrf.html  
  5. Cookie: SESSION=e29a31e41c9512a4bd  
  6. Content-Type: application/x-www-form-urlencoded  
  7. mail=bob@example.com 

下面我们列出攻击者所伪造的HTTP POST请求中的明细:

  • 浏览器发送一个POST请求。
  • 我们例子中的example.com是用户所登录到的一个脆弱的站点。请注意它的referrer和origin都表明请求是来自attacker.com。
  • Cookies的头部信息包含了用户的会话cookie。尽管浏览器请求是被恶意脚本所触发的,但浏览器仍然会将这个Cookie头部连同请求一同发送。由于该请求指向的是example.com,而用户正好具有该网站的会话cookie。这也意味着,Web应用程序会去识别会话里的用户登录状态。
  • Cookie头部的下面一行是Content-Type类型的HTTP,它表明该请求是由一个表单所发出的。
  • 整个post的底部最后一行是参数映射值。此处参数为mail,其值便是攻击者的邮箱地址:bob@attacker.com。

四、用CSRF攻击来诱骗受害者

攻击者是如何使用CSRF攻击来诱骗受害者的呢?让我们假设攻击者将该表单发布到了https://attacker.com/csrf.html。为了诱骗用户浏览到的这个URL,他通常会通过电子邮件的形式去诱骗受害者访问该URL。

因此,一旦受害者访问了https://attacker.com/csrf.html,该表单的提交就会被触发。而那个脆弱的https://example.com网站随即会接受到该请求。由于其Web应用程序根据会话cookie,判定是由受害者亲自提交而来,因此它将邮件地址更改为bob@attacker.com。

接下来,攻击者所需要做的就是发送一封带有“密码重置”功能的电子邮件了。由于电子邮件已经被改成了bob@attacker.com,因此Bob会收到该邮件,并且能够轻而易举地改变Alice的密码了。至此,Bob完全接管了她的帐号,甚至会把她锁在了“门外”。

向受害者隐藏CSRF攻击

为了不使受害者注意到已经遭受了CSRF攻击,攻击者一般会创建另一个称为info.html的网页,来包含一些受害者感兴趣的主题信息。同时,该网页会包含一个指向https://attacker.com/csrf.html的隐藏iframe。一旦受害者访问到了info.html,在csrf.html上的表单就会在受害者不可见的情况下自动触发。

可见,攻击者通常使用CSRF攻击来更改密码或表单上的电子邮件,从而劫持受害者的​​帐户,或是在Web应用上创建一个新的管理员帐号。

五、预防跨站请求伪造攻击

攻击者只有在获知到表单里使用了哪些参数和值的组合时,才能发动CSRF攻击。因此,如果增加一个对于攻击者来说是未知的参数值,并且能够通过服务器端进行验证,那么您就可以防止受到CSRF的攻击。下面我们为您罗列了一些可以用来预防跨站请求伪造攻击的方法。

使用反CSRF的令牌

这是一个只能被用户端的浏览器和Web应用程序所知悉的一个随机字符串。它通常被存储在一个会话的变量中。而且,它通常被放在在网页的一个隐藏表单的字段内,连同请求一起被发送出去。

如果会话的变量值和隐藏的表单字段相匹配的话,Web应用程序就会接受该请求。而如果它们不匹配,则该请求会被Web应用所丢弃。由于在这种情况下,攻击者并不知道可用于接受请求的那个被隐藏表单的精确值,也就无法发动CSRF攻击了。

在cookies中使用相同的站点标志

相同的站点标志(https://www.netsparker.com/blog/web-security/same-site-cookie-attribute-prevent-cross-site-request-forgery/)是一个比较新的,可用来预防CSRF攻击的方法。在上述场景中,https://attacker.com/将带有会话cookie的POST请求发往https://example.com/。该会话cookie对于每一个用户都是唯一的,而Web应用程序可以用它来区分不同的用户,并确定您是否已经登录过。

如果给会话cookie标记上“相同站点的cookie”特征,将它与那些仅来自同一个域的请求一起发送出去。那么,当https://example.com/index.php向https://example.com/post_comment.php发送POST请求时,它就会被允许。而由于https://attacker.com/是在另一个不同的域,它无法将会话cookie连同请求一起发送出去,因此也就不能向https://example.com/post_comment.php产生POST请求了。

最后我们罗列出漏洞分类和严重性的对应表,供您参考。

Classification

ID / Severity

PCI v3.1

6.5.9

PCI v3.2

6.5.9

OWASP 2013

A8

CWE

352

CAPEC

62

WASC

9

HIPAA

164.306(a)

Netsparker

Low

原文标题:What a Cross-Site Request Forgery Attack Is and How to Prevent It,作者: Sven Morgenroth

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

【编辑推荐】

  1. DB-Engines 2017 年度数据库:PostgreSQL 实至名归
  2. 外媒速递:将在2018年重新定义ETL前景的五大数据集成趋势
  3. 360截获“噩梦公式二代”Office 0day漏洞攻击
  4. StackOverflow数据分析:JavaScript框架的残酷生命周期
  5. 年度盘点:安全测试者偏爱的安全测试工具(全免费)
【责任编辑:张燕妮 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

网络管理员考试考前冲刺预测卷及考点解析

本书依据最新版《网络管理员考试大纲》的考核要求,深入研究了历年网络管理员考试试题的命题风格和试题结构,对考查的知识点进行了提炼,并...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊