基于Jwt实现登录功能如何同时避免XSS和CSRF攻击
Jwt Token在浏览器上一般存储在SessionStorage或Cookie当中,存储在SessionStorage可能会被XSS脚本获取,存储在HTTP-only的Cookie则会因“自动随请求发送”的特性受CSRF攻击。
所以此时通过在请求头/uri添加一个CSRF Token来解决CSRF攻击,那这个CSRF Token应该存储在浏览器的哪个位置?CSRF Token不会被XSS获取吗?
基于Jwt实现登录功能如何同时避免XSS和CSRF攻击
Jwt Token在浏览器上一般存储在SessionStorage或Cookie当中,存储在SessionStorage可能会被XSS脚本获取,存储在HTTP-only的Cookie则会因“自动随请求发送”的特性受CSRF攻击。
所以此时通过在请求头/uri添加一个CSRF Token来解决CSRF攻击,那这个CSRF Token应该存储在浏览器的哪个位置?CSRF Token不会被XSS获取吗?
会。因为 XSRF Token 并不是通过 Cookie 来验证的,因为如果使用 Cookie 上行,那么 XSRF 就没有意义了。
那这就意味着,XSRF Token 即使是通过 Cookie 通知给客户端的,也不能设置 HttpOnly,这自然可以被 JS 获取到。
为什么会需要在 Cookie 中下发 XSRF Token 呢?
这很简单,因为我们可以利用浏览器和一些前端请求包(比如 Axios)来帮我自动把 Cookie 中的 XSRF Token 放到 Header 中进行发送。
Axios 在配置了
withXSRFToken
后(在旧版中这个由withCredentials
控制),就会自动解析 Cookie 中XSRF-TOKEN
的值并将他附加到X-XSRF-TOKEN
这个请求头中,后端会使用这个X-XSRF-TOKEN
来与 Session 中保存的 XSRF-Token 进行验证,而不是浏览器在上行请求中发送的 XSRF-Token Cookie。最后要说的是 XSS 和 CSRF 是两个不同的防护点,如果你的站点存在 XSS,那么 CSRF 是防不了的。
也就是说,如果页面存在 XSS,那么 CSRF 就无从谈起。