我们需要将JWT存储在客户端计算机上。如果我们将其存储在LocalStorage / SessionStorage中,那么XSS攻击很容易抓住它。如果我们将其存储在cookie中,则黑客可以在CSRF攻击中使用它(无需阅读)并假冒用户并联系我们的API,并发送代表用户采取行动或获取信息的请求。
但是,有几种方法可以保护cookie中的JWT不易被盗(但仍有一些先进的技术可以窃取它们)。但是,如果您要依赖LocalStorage / SessionStorage,则可以通过简单的XSS攻击对其进行访问。
因此,为了解决CSRF问题,我在应用程序中使用了Double Submit Cookies。
双重提交Cookies方法
将JWT存储在HttpOnly cookie中,并以安全模式使用它来通过HTTPS进行传输。
大多数CSRF攻击在其请求中具有与原始主机不同的来源或引荐来源标头。因此,请检查标头中是否包含其中的任何一个,它们是否来自您的域!如果不拒绝他们。如果请求中没有原始来源和引荐来源网址,则无需担心。您可以依靠X-XSRF-TOKEN标头验证结果的结果,我将在下一步中进行解释。
虽然浏览器将自动为请求的域提供cookie,但存在一个有用的限制:网站上运行的JavaScript代码无法读取其他网站的cookie。我们可以利用它来创建我们的CSRF解决方案。为了防止CSRF攻击,我们必须创建一个额外的Javascript可读cookie,称为:XSRF-TOKEN。该cookie必须在用户登录时创建,并且应包含一个随机的,不可猜测的字符串。我们也将此数字作为私人声明保存在JWT本身中。每当JavaScript应用程序想要发出请求时,它将需要读取此令牌并将其发送到自定义HTTP标头中。由于这些操作(读取Cookie,设置标题)只能在JavaScript应用程序的同一域上进行,
Angular JS使您的生活更轻松
幸运的是,我在平台上使用了Angular JS,并且Angular打包了CSRF令牌方法,这使我们更易于实现。对于我们的Angular应用程序对服务器的每个请求,Angular $http
服务将自动执行以下操作:
- 在当前域中查找名为XSRF-TOKEN的cookie。
- 如果找到该cookie,它将读取该值并将其作为X-XSRF-TOKEN标头添加到请求中。
这样,客户端实现将自动为您处理!我们只需要XSRF-TOKEN
在服务器端的当前域上设置一个名为cookie的cookie ,当我们的API收到来自客户端的任何调用时,它必须检查X-XSRF-TOKEN
标头并将其与XSRF-TOKEN
JWT中的进行比较。如果它们匹配,则用户是真实的。否则,这是伪造的请求,您可以忽略它。此方法受“双重提交Cookie”方法的启发。
警告
实际上,您仍然容易受到XSS的攻击,只是攻击者无法窃取您的JWT令牌供以后使用,但攻击者仍然可以使用XSS代表您的用户发出请求。
无论您将JWT存储在中localStorage
还是将XSRF令牌存储在非HttpOnly cookie中,XSS都可以轻松地将它们两者都捕获。即使是HttpOnly cookie中的JWT,也可以通过高级XSS攻击(例如XST方法)来捕获。
因此,除了Double Submit Cookies方法外,您还必须始终遵循针对XSS的最佳做法,包括转义内容。这意味着删除所有可能导致浏览器执行您不希望执行的操作的可执行代码。通常,这意味着删除// <![CDATA[
导致JavaScript评估的标记和HTML属性。
在这里阅读更多: