我们需要将JWT存储在客户端计算机上。如果我们将它存储在LocalStorage/SessionStorage中,那么它很容易被XSS攻击捕获。如果我们将其存储在cookie中,那么黑客就可以在CSRF攻击中使用它(不读取它),并模拟用户,联系我们的API,并代表用户发送操作或获取信息的请求。
但是有几种方法可以保护cookie中的JWT不容易被窃取(但仍然有一些先进的技术可以窃取它们)。但是如果你想依赖LocalStorage/SessionStorage,那么它可以通过一个简单的XSS攻击来访问。
因此,为了解决CSRF问题,我在应用程序中使用了双重提交cookie。
双提交Cookies方法
Store JWT in a HttpOnly cookie and used it in secure mode to transfer over HTTPS.
Most of CSRF attacks have a different origin or referrer header with your original host in their requests. So check if you have any of them in the header, are they coming from your domain or not! If not reject them. If both origin and referrer are not available in the request then no worries. You can rely on the result of X-XSRF-TOKEN header validation results which I explain in the next step.
While the browser will automatically supply your cookies for the domain of the request, there is one useful limitation: the JavaScript code that is running on a website cannot read the cookies of other websites. We can leverage this to create our CSRF solution. To prevent CSRF attacks, we must create an extra Javascript readable cookie which is called: XSRF-TOKEN. This cookie must be created when the user is logged in and should contain a random, un-guessable string. We also save this number in the JWT itself as a private claim. Every time the JavaScript application wants to make a request, it will need to read this token and send it along in a custom HTTP header. Because these operations (reading the cookie, setting the header) can only be done on the same domain of the JavaScript application, we can know that this is being done by a real user who is using our JavaScript application.
Angular JS让你的生活变得简单
幸运的是,我在我们的平台上使用的是Angular JS, Angular封装了CSRF令牌方法,这让我们更容易实现它。对于Angular应用程序向服务器发出的每一个请求,Angular $http服务都会自动执行以下操作:
在当前域中查找名为XSRF-TOKEN的cookie。
如果找到该cookie,它将读取该值并将其作为X-XSRF-TOKEN报头添加到请求中。
因此,客户端实现将自动为您处理!我们只需要在服务器端的当前域上设置一个名为XSRF-TOKEN的cookie,当我们的API从客户端得到任何调用时,它必须检查X-XSRF-TOKEN报头,并将其与JWT中的XSRF-TOKEN进行比较。如果匹配,则用户是真实的。否则,这是一个伪造的请求,你可以忽略它。这种方法的灵感来自于“Double Submit Cookie”方法。
谨慎
在现实中,你仍然容易受到XSS的影响,只是攻击者不能窃取你的JWT令牌供以后使用,但他仍然可以使用XSS代表你的用户发出请求。
无论你将JWT存储在localStorage中,还是将XSRF-token存储在非HttpOnly cookie中,都可以被XSS轻松获取。甚至你在HttpOnly cookie中的JWT也可能被XST方法这样的高级XSS攻击捕获。
因此,除了Double Submit Cookies方法之外,还必须始终遵循针对XSS的最佳实践,包括转义内容。这意味着删除任何可能导致浏览器执行您不希望它执行的操作的可执行代码。通常这意味着删除// <![CDATA]标签和HTML属性,导致JavaScript被计算。
点击此处阅读更多信息:
Angular的XSRF:如何工作
在哪里存储您的jwt - cookie vs HTML5 Web存储