我读到使用JWT时,没有必要防范CRSF攻击,例如:" since you are not relying on cookies, you don't need to protect against cross site requests"。
但是,我不明白:如果我将令牌存储在localStorage中(因为我被告知on a tutorial of the same website),是什么阻止攻击者通过读取我的localStorage而不是我的cookie来伪造恶意请求?
由于它是在服务器端生成的,因此我不知道如何将令牌用于客户端请求而不将其存储在客户端的某个位置。
答案 0 :(得分:89)
严格来说,是的,存储在本地/会话存储中的任何内容(我称之为HTML5存储)都可能在跨站点脚本(XSS)攻击中被盗。请参阅this article。
然而,有许多可动部件需要考虑。
首先,HTML5存储和Cookie在JavaScript访问方面的作用方式存在细微差别。
HTML5存储是:
http://example.com
上运行的JavaScript无法访问存储在https://example.com
HTML5存储空间中的项目。http://example.com
上运行的JavaScript无法访问存储在http://sub.example.com
HTML5存储空间中的项目(您可以执行一些tricks来解决此问题)。饼干更松散了:
example.com
的Cookie将同时转到http://example.com
和https://example.com
,除非它具有属性secure
,在这种情况下它只会发送到https
。example.com
,则会将其发送给example.com
和sub.example.com
。 (这是cookie中最令人困惑的部分" spec",不幸的是,请参阅this article)。secure
cookie标志),则可以通过JavaScript读取cookie,除非该cookie具有httpOnly
属性,在这种情况下,JavaScript将无法读取它。其次,由于Cookie是使用域标记的,因此当向服务器发出请求时,浏览器将发送具有匹配域的所有cookie,而不管源自哪个域的域。请求
最后一部分是如何完成CSRF攻击(同源政策只能帮助这么多)。 OWASP page on CSRF是了解这类攻击如何运作的良好资源。
将身份验证令牌存储在本地存储中并手动将其添加到每个请求的原因可以防止CSRF成为关键字:manual。由于浏览器没有自动发送该身份验证令牌,如果我访问evil.com
并且它设法发送POST http://example.com/delete-my-account
,则无法发送我的身份验证令牌,因此会忽略该请求。
考虑到上述因素,无论是使用cookie还是HTML5存储都会成为一系列权衡因素:
将身份验证令牌存储在HTML5存储中意味着:
(-)
在XSS攻击中被盗的风险。(+)
提供CSRF保护。(-)
必须手动修改发往服务器的每个请求,限制您使用SPA(例如AngularJs)Web应用程序。另一方面,如果您将authn令牌存储在标记为httpOnly
和 secure
的Cookie中,则:
(+)
XSS无法盗取authn令牌。(-)
您必须自己提供CSRF保护。在某些框架中实施CSRF保护比其他框架更容易。哪种选择更好取决于您的需求。
httpOnly
secure
选项。答案 1 :(得分:1)
使用基于令牌的身份验证时,必须手动将令牌与请求关联。与Cookie相反,浏览器不会自动设置令牌,因此不易受到csrf
攻击。
尽管这种方法可以防止csrf
攻击,但很容易受到xss
攻击。
最省力的改进是使用session storage
而不是local storage
,因为session storage
数据在用户关闭标签/浏览器后便被清除。