标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-3276]   作者: 闲云野鸡 发表于: [2023-02-24]

本文共 [109] 位读者顶过

跨站请求伪造(Cross Site Request Forgery, CSRF),也被称为 One Click Attack 或者 Session Riding ,是一种在用户不知情条件下攻击者利用网站信任已认证用户身份执行非用户预期行为的漏洞。CSRF 漏洞往往是 Web 漏洞中最容易被忽略的漏洞,虽然通过遵循安全开发规范可以避免这种漏洞的出现,但依然有很多开发者并不了解正确的 CSRF 防御性编程方法,在代码中留下了 CSRF 漏洞。若网银系统存在 CSRF 漏洞,可能会造成受害者在不知情的情况下进行交易、支付等行为,造成财产损失。

Cookie 作为网站为了辨别用户身份而存储在客户端的数据,经常被用于验证客户端的用户身份,可以起到会话识别、会话保持的作用。当客户端第一次访问某网站时,服务端往往会返回一个 Cookie 作为客户端的凭证,客户端在后续的网站访问过程中会自动发送该 Cookie 。目标网站通过读取 Cookie 即可得知用户的相关信息,根据识别出的用户身份提供相关权限的页面展示和交互功能,所以用户在使用 Web 应用的过程中不用频繁输入用户名、密码来验证身份。

CSRF 最主要是利用了「浏览器会按照一定的规则在后台自动发送 Cookie 给 Web 服务器」这个特性,被攻击者在访问到包含 CSRF 攻击代码的网页时会由浏览器在后台自动执行包含目标网站 Cookie 的攻击代码完成仿冒被攻击者身份执行恶意操作目的。一个典型的 CSRF 漏洞利用过程如下: 

            1、 用户登录了受信任的网站 A,并在浏览器本地存储了该 Cookie。     

            2在不登出网站 A 的前提下(关闭浏览器并不代表 Cookie 过期或失效),访问了恶意网站 B。      

           3、 恶意网站 B 要求用户(不展示任何有关网站 A 的页面信息)发出一个请求(POST 或 GET)到网站 A。对于这一步的攻击主要是利用了「浏览器在访问目标 Web 站点时会自动将保存在浏览器中的目标站点 Cookie 发送过去」这个特性。以被攻击者在目标站点的用户身份(目标站点根据当前发送出去的 Cookie 来验证用户身份)发起伪造的 HTTP 请求。       

           4、 根据上一步恶意网站的操控行为,用户在不知情的前提下,带着自己在网站 A 获得的 Cookie 向网站 A 发送了请求。            

           5、存在 CSRF 漏洞的目标受信任站点(网站 A)误以为所有通过了身份验证的请求都是「代表了用户本人意图」而没有考虑到通过 CSRF 漏洞利用方式发起的请求是「被劫持 Cookie 或其他身份认证凭据后伪造」的自动化、非用户本人主动发起的请求。因此受信任的网站 A 根据 Cookie 信息,认为这是可信任用户发送的请求,接受并处理了这个请求。

 在上述典型 CSRF 漏洞利用过程中,CSRF 漏洞存在于网站 A 的服务端代码,用户访问恶意网站 B 并不是触发 CSRF 漏洞的必要条件。如果网站 A 同时存在跨站点脚本漏洞,则攻击者通过在网站 A 上利用跨站点脚本漏洞方式也可以让用户在不知情情况下,触发相关页面的 CSRF 漏洞攻击。

以下 PHP 脚本片段是一个包含 CSRF 漏洞关键代码的实例:

假设一个用户信任的社交 Web 应用程序在服务端实现了一个添加好友的接口,可以使用形如 http://victim-trusted.com/Addfriend.php?userid=123 的 GET 请求来进行添加好友的操作,脚本内部实现方法如下:

<?php session_start(); if (is_authorized()){ if (isset($_GET['userid'])){

    add_friend($_GET['userid']);
  }
}
   该脚本实际上违反了 HTTP 规范,没有使用表单提交的方式(即 POST 方式)而是使用 GET 请求更新资源。攻击网站只需在 HTML 代码中构造如下一个带有危险请求链接的图片即可使受害者在不知情的情况下主动添加陌生人为好友。

<img src="http://victim-trusted.com/Addfriend.php?userid=233">
    服务端脚本使用 POST 参数的方式可以从一定程度上加大漏洞利用的难度,提高安全性,但 CSRF 漏洞依旧是存在的 
<html> 
<head> 
<script type="text/javascript"> function steal() {
  iframe = document.frames["steal"];
  iframe.document.Submit("Addfriend");
} </script> 
</head> 
<body onload="steal()"> 
<iframe name="steal" display="none"> 
 <form method="POST" name="Addfriend" action="http:// victim-trusted.com/Addfriend.php"> 
 <input type="hidden" name="userid" value="233"> 
 </form>  
</iframe> 
</body> 
</html>
   上述代码中,恶意网站通过嵌入一个包含恶意表单的隐藏 iframe,可以通过 JS 动态执行的方法,在受害者不知情的情况下自动提交 POST 请求,从而主动添加了陌生人为好友。
   CSRF 漏洞的源代码级别加固有以下四种方法:
   1、对 HTTP Header 中的 Referer 字段进行验证。HTTP Referer 字段记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站。比如社交网站的添加好友操作是通过用户访问 
http://victim-trusted.com/Addfriend.php?userid=123 页面完成,用户必须先登录 victim-trusted.com,然后通过点击页面上的按钮来发送添加好友的请求。该请求的 Referer 值是当前页面的 URL (以 victim-trusted.com 开头)。而对于攻击者而言,利用
 CSRF 漏洞构造的请求的 HTTP Referer 值只能是指向攻击者的网站。因此,要防御 CSRF 攻击,可信网站只需要对于每一个 POST 请求验证其 Referer 值,如果是以 victim-trusted.com 开头的域名,则说明该请求是来自本网站的合法请求;如果 Referer 是其他网站
的话,就有可能是 CSRF 攻击,则拒绝该请求。
   2、在 POST 请求中添加 token 作为参数并验证。这种安全策略被各种 Web 框架广泛采用(包括 Laravel 等)。CSRF 漏洞能够被利用的主要原因就是用户的全部验证信息均保存在 Cookie 中,攻击者可以在不接到 Cookie 的前提下完成身份验证。因此,只需在请求中
设置一个攻击者所无法伪造的、不可预测的 token,且保证这个 token 与 Cookie 是毫无关联的。此外,还应保证这个 token 是独立且不重复使用的。在服务端验证用户身份时应同时对 Cookie 及 token 进行验证。这个 token 被称为 csrftoken,在 HTML 的表单中,
该字段的输入域往往是隐藏的。
   3、在 HTTP 头中自定义属性并验证。自定义属性的方法也是使用 token 并进行验证,和前一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP Header 中自定义的属性里。当前一种方法实现不便的情况下,可以采用这种安全策
略进行系统加固。
   4、添加验证码并验证。可以在表单中增加随机验证码,采用强制用户与 Web 应用进行交互的方式防止 CSRF 攻击。这种方式适用于登录验证、交易等针对危险操作的接口,但强制所有请求都使用验证码往往也是不现实的。因此是否采用这种安全策略应该根据具体情况来决定。
   在实战中, Web 程序往往采用在 POST 请求中添加 token 作为参数并验证的方法作为防止 CSRF 漏洞的安全策略。应该注意的是,不要将 csrftoken 作为 GET 参数进行请求,防止请求地址被记录到浏览器的地址栏,也防止 token 通过 Referer 泄露到其他网站。
[出自:jiwo.org]



评论

暂无
发表评论
 返回顶部 
热度(109)
 关注微信