跨站点请求伪造 CSRF

CSRF: Cross Site Request Forgery

CSRF 的防御

验证码

CSRF 攻击的过程,往往是在用户不知情的情况下构造了网络请求。因此在通常情况下,验证码能够很好地遏制 CSRF 攻击。

但是验证码并非万能。很多时候,处于用户体验考虑,网站并不能给所有的操作都加上验证码。

Refer Check

Refer Check 在互联网中最常见的应用就是防止图片盗链:

  • 盗链:服务商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的服务内容,骗取最终用户的浏览和点击率。

通过同样的原理,Refer Check 也可以用于检查请求是否来自合法的 “源”。

即使我们能够通过检查 Refer 是否合法来判断用户是否被 CSRF 攻击,也仅仅是满足了防御的充分非必要条件。Refer Check 的缺陷在于,服务器并非任何时候都能取到 Refer。很多时候处于隐私考虑、或者是浏览器限制了 Refer 的发送。

因此我们无法依赖 Refer Check 作为防御 CSRF 的主要手段。但是我们可以用它监控 CSRF 攻击的发生。

Anti CSRF Token

CSRF 为什么可以攻击成功呢?

  • 其本质原因是,重要操作的所有参数都是可以被攻击者猜测的。攻击者只有预测除了 URL 的所有参数与参数值,才能成功地构造一个伪造的请求。
  • 处于这个原因我们可以使用一些随机数把参数加密,使攻击者无法猜测到参数值。

这种方式就叫做 Anti CSRF Token

因为 Token 的存在,服务器只需要验证表单中的 Token 与用户的 Session(或 Cookie)中的 Token 是否一致,如果一致则认为是合法请求;否则非法。

使用 Anti CSRF Token 的时候需要注意:

  1. Token 的生成一定要足够随机,需要使用安全的随机数生成器生成 Token;
  2. Token 的目的不是为了防止重复提交。为了使用方便,可以允许在一个用户的有效生命周期内,都使用同一个 Token。如果用户已经提交了表单,应当重新生成一个;
  3. 如果用户打开多个窗口,应当考虑生成多个有效 Token,解决多页面共存问题;
  4. 注意 Token 的保密性。不应该发送 GET 请求,导致出现在某个页面的 URL 中;

CSRF 的 Token 仅仅用于对抗 CSRF 攻击,当网站还存在 XSS 漏洞时,这个方案就会变得无效。在 XSS 攻击下,攻击者完全可以请求页面后,读出页面内容里的 Token 值,再构造一个合法的请求,这个过程可以称之为 XSRF,和 CSRF 以示区分。