文章

XS-Leak学习记录----前置知识

前言

XS-Leaks 的本质是Web侧信道攻击

不同于XSS直接执行代码获取敏感信息,XS-Leaks利用浏览器在处理跨站请求时的细微差异,推断用户的状态或敏感数据

国际赛关于XSS以及xsleak的考察呈逐渐增加的趋势,所以想着系统性的学学xsleak

学习过程中使用了llm等作为辅助,因此文章内容可能有错,如有错欢迎指正(

内容有点多,而且学习这个体系需要一定时间,因此分开来写


XS-Leaks 攻击成立有以下三个要求:

  1. 浏览器发送跨站请求时携带了凭证

  2. Oracle (预言机):攻击者能观测到的差异。例如:响应时间不同、HTTP状态码不同、DOM元素数量不同、触发的JS事件不同

  3. Oracle 的输出结果依赖于用户的敏感数据状态

为了达成这三个要求,我们需要先了解些前置知识(同源策略,CORS,隔离策略,SameSite属性)

同源策略(SOP)

xsleak是浏览器发起跨域请求时的攻击手段

因此我们首先要了解什么是同源,什么是跨域

可以参考:浏览器的同源策略 - 安全 | MDN

简单来说,如果两个URL的协议,端口和host都相同的话,则这两个 URL 是同源的。反之则不同源

SOP 默认允许跨域写入 (form post) 和跨域嵌入 (script, img, iframe, link),但禁止跨域读取 (fetch)

为了解决“需要合法跨域读取”的问题,引入了CORS机制

为了解决“SOP 允许了太多不该允许的跨域嵌入和引用”的问题,引入了隔离策略

接下来简要介绍下两个策略

CORS

此部分可以参考

跨源资源共享(CORS) - HTTP | MDN

浏览器将请求分为两类:

  • 简单请求 (Simple Request):(GET/POST/HEAD, 无自定义头, 部分Content-Type)

    该请求下浏览器不会发起预检请求,流程大概是,浏览器直接发出请求 -> 服务器返回数据 -> 浏览器检查响应头 Access-Control-Allow-Origin

    如果ACAO不匹配,请求已发送并在服务端处理,浏览器只是拦截了响应数据的读取

  • 预检请求 (Preflight Request):(PUT/DELETE, 自定义头, JSON等)

    流程是,浏览器先发 OPTIONS -> 服务器确认允许 -> 浏览器发送实际请求

CORS主要有两类响应头

  • Access-Control-Allow-Origin (ACAO): 指定允许的源

    • *: 允许所有,但此时无法携带cookie

    • https://xxx.com: 允许指定源

  • Access-Control-Allow-Credentials (ACAC): true / false.

    只有为 true 时,JS 才能携带cookie并读取到跨域请求返回的内容

隔离策略

场景:攻击者页面 window.open('https://xxx.com'),持有 window 引用,可进行 XS-Leaks 探测或通过 opener 互相影响

因此需要切断页面间的 window 引用关系,控制浏览上下文组

该策略主要响应头是Cross-Origin-Opener-Policy (COOP)

  • unsafe-none (默认): 允许跨域窗口引用,允许加入同一浏览上下文组

  • same-origin: 强隔离 当前页面会在一个独立的进程中运行 切断与打开者或被打开者的联系 window.opener为 null

  • same-origin-allow-popups: 允许当前页面打开的弹窗保留引用(除非弹窗也设了 COOP)

Framing Isolation Policy (FIP)

控制iframe嵌入,主要响应头:

X-Frame-Options (XFO) :

  • DENY: 禁止被嵌入

  • SAMEORIGIN: 仅同源可嵌入

或者利用CSP:

  • Content-Security-Policy: frame-ancestors 'none'; (等同 DENY)

  • Content-Security-Policy: frame-ancestors https://xxx.com; (白名单)

Resource Isolation Policy (RIP)

SOP 默认允许 <img src="https://xxx.com/xxx.png">。虽然 JS 读不到内容,但这会触发侧信道攻击

因此需要控制资源(图片、脚本、视频)加载

主要响应头:Cross-Origin-Resource-Policy (CORP)

  • cross-origin (默认): 允许任何人嵌入

  • same-site: 仅同一站点可嵌入

  • same-origin: 仅完全同源可嵌入

Cross-Origin Embedder Policy (COEP)

这个头比较特殊

为了安全,浏览器默认禁用了 SharedArrayBuffer。 要想重新启用 SharedArrayBuffer 和高精度计时器,页面必须进入跨域隔离状态

进入该状态的条件是:

  1. COOP: same-origin (独立进程)

  2. COEP: require-corp (确保加载的所有资源都是安全的)

这里COEP 的作用是:强制要求当前页面加载的所有跨域资源(Image, Script, Style, Iframe...),必须显式声明CORP或者CORS

如果页面设置了: Cross-Origin-Embedder-Policy: require-corp

那么,浏览器在加载任何跨域资源时,会检查该资源的响应头:

  • 是否有 Cross-Origin-Resource-Policy (CORP)

    • 如果是跨域资源,必须有 CORP: cross-origin

    • 如果是同站资源,必须有 CORP: same-site

  • 或者是否有 Access-Control-Allow-Origin (CORS)

    如果有合法的 CORS 头,也视为通过

如果资源没有上述头部,浏览器将拦截加载

COEP策略值:

  • unsafe-none (默认):

    • 不进行强制检查

  • require-corp:

    • 强约束模式

  • credentialless:

    • 无凭证模式

    • 如果第三方资源没有 CORP 头也允许加载,但浏览器在发送请求获取该资源时,不携带任何凭证

归纳

隔离内容

Headers

作用

导航/窗口

COOP

切断 window 引用

嵌入/框架

CSP/ XFO

禁止被 iframe 嵌入

资源加载

CORP

禁止资源被跨站标签加载

加载者约束

COEP

强制要求所有子资源均合法

数据读取

CORS

允许/禁止 JS 读取响应内容

SameSite

XS-Leaks 中,核心的一点是要让浏览器带上cookie。如果没带上cookie,服务器返回内容便没有差异化,Oracle 也就失效了

Cookies中的SameSite属性则是控制跨站请求时,Cookie是否跟随发送的核心机制之一

前面讲到,同源是协议 + 域名 + 端口相同

而SameSite属性中的Site(站)的要求则是etld+1,也就是相同的顶域

例如a.example.comb.example.com 是同站

SameSite限制的是跨站请求,而不是跨源请求

该属性有三种模式

模式

描述

Strict

严格模式 任何跨站请求(包括点击链接跳转)都不发送 Cookie

Lax

宽松模式 (默认)

None

无限制 必须配合 Secure 属性 任何请求都带 Cookie

由于未设置该属性时,默认为Lax,因此我们主要研究该情况下的场景

Lax允许发送Cookie的场景:

  • 用户点击链接 <a> 跳转到目标站

  • window.open('https://xxx.com') 打开新窗口

  • form 表单提交(仅限 GET 方法)

Lax 禁止发送 Cookie 的场景:

  • <iframe> 嵌入目标站

  • <img> 加载图片

  • fetch 请求


未完待续......

许可协议:  CC BY 4.0