即使存在 XSS 漏洞,CSRF 保护也能工作吗?

信息安全 Web应用程序 xss csrf
2021-09-08 18:07:03

需要抵御 XSS 攻击的 CSRF 保护

XSS 的一大危险是它通常可以绕过 CSRF 保护,从而执行受害者可以执行的任何操作。

如果即使存在 XSS 漏洞也可以阻止 CSRF,那么这似乎将大大减轻 XSS 可能造成的损害。由于 httpOnly,可能无法窃取 cookie,这会使攻击者遭受网络钓鱼攻击、污损和读取客户端可访问的数据。

但 OWASP 表示,一旦存在 XSS 漏洞,就不可能阻止 CSRF。

使用推荐人检查进行适当的 CSRF 保护?

即使存在 XSS 漏洞,是否应该可以使用引荐来源检查作为 CSRF 保护?

当然,域检查是不够的。但是,如果检查了确切的脚本,它不会起作用吗?

例如,如果从 发送请求http://example.com/add-user.php,则要求引用者是http://example.com/add-user.php

这仍然意味着攻击者可以对该脚本执行 CSRF,如果该脚本包含 XSS 漏洞,但不应对同一域上的不同脚本进行 CSRF 攻击,因为无法通过 JavaScript 设置引荐来源网址。

  • 推荐人检查可能并不总是实用的(例如,因为客户端不发送推荐人),但如果使用它们,是否可以以这种方式使用它们?
  • 如果它们可以像这样使用,这种方法是否存在重大缺点?
  • 如果没有,如果存在 XSS 漏洞,理论上是否存在有效的 CSRF 保护?
2个回答

不,我不这么认为。它可以通过创建一个display: none包含页面的 iframe 来规避add-users.php然后攻击者所要做的就是填写表单字段并使用 JavaScript 提交表单,攻击者在没有受害者同意或不知情的情况下成功添加了一个用户。检查referer标头不会阻止此操作,因为它具有正确的值。

OWASP关于使用引用者进行 CSRF 保护有以下说法:

尽管在您自己的浏览器上欺骗referer 标头是微不足道的,但在CSRF 攻击中是不可能做到的。检查引用是在嵌入式网络设备上防止 CSRF 的常用方法,因为它不需要每个用户的状态。当内存不足时,这使得引用者成为防止 CSRF 的有用方法。这种缓解 CSRF 的方法也常用于未经身份验证的请求,例如在建立会话状态之前发出的请求,该会话状态需要跟踪同步令牌。

但是,检查引用者被认为是 CSRF 保护的弱点。例如,开放式重定向漏洞可用于利用受引用者检查保护的基于 GET 的请求,并且某些组织或浏览器工具会删除引用者标头作为一种数据保护形式。引用者检查也存在常见的实现错误。例如,如果 CSRF 攻击源自 HTTPS 域,则引用者将被省略。在这种情况下,当请求执行状态更改时,应将缺少引用者视为攻击。另请注意,攻击者对引用者的影响有限。例如,如果受害者的域是“site.com”,那么攻击者的 CSRF 漏洞利用源自“site.com.attacker.com”,这可能会欺骗损坏的引用检查实现。

简而言之,Referer Check 是 CSRF 入侵检测和预防的一种合理形式,尽管它不是一种完整的保护。Referer 检查可以检测到一些攻击,但不能阻止所有攻击。例如,如果您的 HTTP 引荐来源网址来自不同的域,并且您只期望来自您的域的请求,您可以安全地阻止该请求。

(顺便说一句,我认为解决这个问题会“大大减轻” XSS 的损害。除了您列出的其他内容之外,攻击者仍然可以窃取密码。这仍然很糟糕。)

即使存在 XSS 漏洞,是否应该可以使用引荐来源检查作为 CSRF 保护?

不。如果你是注入脚本,你可以创建一个<form>指向同源的指针,包含一个被盗的 CSRF 令牌,并使用预期的Referer标头提交它。(当然,推荐人检查通常是有问题的,如果这是一个使用 XHR 做任何事情的应用程序,则不太可能有任何用处。)

但是,如果检查了确切的脚本,它不会起作用吗?

不。一旦进入原点,就没有内部安全边界。注入的脚本可以打开源中的任何 URL(例如,在 iframe 或弹出窗口中)并将任意脚本直接注入该窗口,从那里它将返回确切的预期引荐来源网址。(现在使用 HTML5 History API,您无论如何都可以直接更改当前文档的 URL。)

用户几乎无法通过与该页面上的脚本无法复制的网页进行交互来做任何事情。所以 OWASP 在这一点上是对的:通常 XSS 给你的漏洞超集比 XSRF 更严重。一旦它发生,您就无法采取任何有效的措施来减轻它,这就是为什么重点通常放在正确处理/转义文本以避免首先发生注入的原因。