论如何防止 CSRF 攻击

94 阅读2分钟

造成 CSRF 漏洞的根本原因是服务端使用 cookie 数据,直接或间接的作为验证用户身份的依据。因为浏览器不管是在哪个站点下点击链接,都会自动的把该链接对应域下的 cookie 添加到请求头上。

比如最简单的认证实现方式是登录时把用户信息记录到 session 中,之后服务端根据 cookie 中的 sessionid 类似的字段查找对应的 session 去获取用户信息。该实现问题出在服务端无法根据请求头数据判定该操作是用户意愿,还是他人恶意添加诱导用户点击的链接。

在使用 session 记录用户登录信息的情况下防止 CSRF 攻击

  1. 可以在登录认证成功后,生成随机的字符串作为 CSRF 令牌,并添加到 session 和 cookie 中。

image.png

  1. 浏览器端判断响应头上有 CSRF 令牌,则把该 CSRF 令牌添加到 localStorage 中和从 cookie 中移除该 CSRF 令牌。

image.png

  1. 之后浏览器在发送给服务端的请求头带上 CSRF 令牌。

image.png

  1. 服务端比对请求头上 CSRF 令牌是否和 session 中的 CSRF 令牌是否一致,作为判断是否 CSRF 攻击的依据。

不使用 session 记录用户登录信息的情况下防止 CSRF 攻击

比如浏览器端把服务端返回的访问令牌存放到 localStorage 中,然后在向服务端发请求时添加该访问令牌,那么不满足被 CSRF 攻击的条件。

不使用 session 但支持记住密码功能的情况下防止 CSRF 攻击

虽然 CSRF 攻击造成的请求不会带上访问令牌,但会把保存在 cookie 中的 remember-me 自动添加到请求头上,服务端将会根据 remember-me 自动登录,也就满足被 CSRF 攻击的条件。此种情况解决的方式跟使用 session 记录用户登录信息的情况下相似,通过添加到浏览器 localStorage 的 CSRF 令牌解决,不同的是服务端要在不使用 session 的情况下验证请求头上的 CSRF 令牌。