假设我们在表单中使用了 CSRF 令牌,但碰巧我们的网站上有一个未被注意到的 XSS 漏洞。
据我了解,在这种情况下,CSRF 令牌保护完全无效,因为攻击者可以通过 XSS 使用 XMLHttpRequest 检索它。
在这种情况下,有没有办法让 CSRF 保护在攻击中幸存下来,或者我们的网站在做任何 CSRF 之王之前应该首先拥有安全的反 XSS 保护?
在每个页面请求上设置一个新令牌而不是在登录时设置一个令牌会处理它吗?这带来了一次打开更多表单的问题,我不喜欢它。
您的站点应该已经关闭了您发现的所有 XSS 漏洞,否则 CSRF 将毫无用处。但是,并行添加 CSRF 会很有用,这样一旦所有 XSS 错误都得到修复,站点的 csrf 保护也可以正常工作。
不幸的是,如果存在 XSS 漏洞,则无法防止 CSRF,因为通过 XSS 漏洞,攻击者可以读取您的网站并检查令牌(使用 javascript)。因此,无论您以何种方式和任何位置添加令牌,都可以找到该令牌,然后对其进行屏幕截图
但是,如果您确保重要页面上没有 XSS 错误,然后添加 CSRF 保护,仍然存在安全漏洞,但是将多个错误链接在一起所需的技能水平会更加困难。
简短的回答: Origin header check
是唯一的csrf保护机制,即使存在 XSS 漏洞,它也能站稳脚跟。
这些是我们用来防止 CSRF 的技术
使用 Synchronizer Token 方法,服务器在输入表单中嵌入一个动态隐藏变量(注意,服务器必须对表单生成具有绝对控制权,以便它可以生成随机字符串并嵌入到表单中)并将其保存在服务器端的会话-> 验证表单提交,并在使用一次后立即将其从会话中失效。这不适用于支持完全分离的 SPA(单页应用程序)的 Restful 服务,因为微服务无法访问 SPA 的表单生成机制。提交表单时,服务器可以检查并确保隐藏变量存在并且它是正确的值。看,这是在正文中发送的(如果我们将这个新令牌设置为 cookie 而不是表单正文,它会破坏整个事情,
如果 mybank.com 没有清理表单输入(或者换句话说,如果 mybank.com 容易受到 xss 攻击),黑客可以克服这种 csrf 预防方法。https://rileykidd.com/2013/09/09/using-xss-to-csrf/
使用双重提交 Cookie 方法,会将两个 cookie 发送回浏览器。一个是会话 id,另一个是随机值(类似于同步器令牌)可以说sessionid
是csrfid
那些 cookie。
有两件事可以使这种机制发挥作用。
1) 内置于浏览器中的功能称为Same Origin Policy
. 这仅允许脚本代码与其他服务器端点交互,前提是这些端点与传递所述脚本代码的端点具有相同的来源(基本 URI)。你可能会想,“哇!如果一个 cookie 本身不安全,那么两个 cookie 如何更安全?” 等等,关键在下一个点
2) 将第二个 cookie ( csrfid
) 包含在自定义标头中的后续请求中(比如说,X-XSRF-Token
)。由您的客户端脚本代码来确保正确设置。
当您请求登录页面时,服务器会发回两个 cookie。第二个 cookie 用于来自浏览器的后续请求的自定义标头。服务器检查自定义标头是否存在,并根据为该页面发送的内容检查该值。
与 Synchronizer Token 方法类似,外部站点试图欺骗页面并诱骗您将数据提交到活动会话,将会失败,因为它无法为不同 URL 的站点设置自定义标头。
服务器必须生成一个随机值 csrftoken cookie 并在会话建立时将其发送到浏览器。
客户端需要访问 cookie 并为每个后续请求设置自定义标头
服务器需要验证 CUSTOM HEADER(只需忽略csrfid
(或您提供的任何名称)cookie。由于它是一个 cookie,无论如何它都会与每个请求一起出现,只需忽略它)
这种技术是有效的,因为所有浏览器都实现了相同的源策略。只有设置了 cookie 的网站中的代码才能从该站点读取 cookie 并为对该站点的请求设置自定义标头。
开放式问题(还没有机会对此进行测试):httpOnly
第二个(csrf-token)cookie怎么样......我们是否需要设置它?.. 如果我们设置它,Javascript 是否能够访问它来设置每个后续请求。另一方面,如果 Javascript 能够访问它,那么再加上 un-sanitized-form-negligence XSS 漏洞,XSS 攻击可以暴露用户的 csrf-token。然后,如果 evil-guy 能够欺骗用户访问 evil-site-which-has-a-csrf-form.com,同时在 mybank.com 中进行活动会话,则可能发生 csrf 攻击。同意,有太多的“如果”可以进行攻击,但仍然不安全。
到目前为止,如果存在 XSS 漏洞,这些方法都不是那么有效。让我们看看第 3 个选项
Origin
所有浏览器(包括 Internet Explorer 9 及更高版本)都会在其请求中发送标头。Javascript 不允许设置此标头,这使您可以高度确信浏览器在该标头中具有正确的信息。然后,服务器可以显式检查该标头并验证基本 URI 是否与服务器的匹配。如果服务器设置为拒绝 Origin 标头中的基本 URI 与预期值不匹配的浏览器请求,则试图欺骗您页面外观的第三方站点将被挫败,因为浏览器中设置的 Origin 将是与预期的不同。
即使 mybank.com 存在 XSS 漏洞,这也不会失败。抓住纳达!如果您的用户使用(非常)旧版本的浏览器,您可能还有其他问题需要解决:)
参考: https ://stormpath.com/blog/secure-single-page-app-problem