首页 文章

在浏览器中存储JWT的位置?如何防范CSRF?

提问于
浏览
97

我知道基于cookie的身份验证 . SSL和HttpOnly标志可用于保护MITM和XSS的基于cookie的身份验证 . 但是,为了保护CSRF免受CSRF的影响,需要采取更多特殊措施 . 它们有点复杂 . (reference

最近,我发现JSON Web Token(JWT)作为一种身份验证解决方案非常热门 . 我知道有关编码,解码和验证JWT的内容 . 但是,我不明白为什么有些网站/教程在使用JWT时不需要CSRF保护 . 我已经阅读了很多,并试图总结下面的问题 . 我只是希望有人可以提供JWT的全貌并澄清我对JWT误解的概念 .

  • 如果JWT存储在cookie中,我认为它与基于cookie的身份验证相同,只是服务器不需要有会话来验证cookie /令牌 . 如果没有实施特殊措施,CSRF仍存在风险 . JWT不是存储在cookie中吗?

  • 如果JWT存储在localStorage / sessionStorage中,那么没有cookie所以不需要防止CRSF . 问题是如何将JWT发送到服务器 . 我发现here建议使用jQuery通过ajax请求的HTTP头发送JWT . 那么,只有ajax请求才能进行身份验证吗?

  • 此外,我发现还有一个blog节目使用"Authorization header"和"Bearer"来发送JWT . 我不明白博客谈论的方法 . 有人可以解释一下"Authorization header"和"Bearer"的更多信息吗?这是否通过所有请求的HTTP头传输JWT?如果是的话,CSRF怎么样?

2 回答

  • 43

    JWT令牌很受欢迎,因为它们在新授权和身份验证协议(如OAuth 2.0OpenID Connect)中用作默认令牌格式 .

    当令牌存储在cookie中时,浏览器会自动将其与每个请求一起发送到同一域,这仍然容易受到CSRF攻击 .

    承载认证是HTTP中定义的authentication schemes之一 . 它基本上意味着 YOU 将(JWT)令牌粘贴在请求的Authorization HTTP标头中 . 浏览器将自动为您执行此操作,因此它不适合保护您的网站 . 由于浏览器不会自动将标头添加到您的请求中,因此它不容易受到CSRF攻击,这取决于您自动提交到原始域的身份验证信息 .

    承载方案通常用于保护通过AJAX调用或移动客户端使用的Web API(REST服务) .

  • 94

    我们需要将JWT存储在客户端计算机上 . 如果我们将它存储在LocalStorage / SessionStorage中,那么它很容易被XSS攻击抓取 . 如果我们将其存储在cookie中,那么黑客可以在CSRF攻击中使用它(不读取它)并冒充用户并联系我们的API并发送请求以执行操作或代表用户获取信息 .

    但有几种方法可以确保JWT在cookie中不被轻易窃取(但仍有一些先进技术可以窃取它们) . 但是,如果您想依赖LocalStorage / SessionStorage,那么可以通过简单的XSS攻击来访问它 .

    因此,为了解决CSRF问题,我在我的应用程序中使用Double Submit Cookies .

    双提交Cookie方法

    • 将JWT存储在HttpOnly cookie中,并在安全模式下使用它通过HTTPS传输 .

    • 大多数CSRF攻击在其请求中与原始主机具有不同的来源或引荐来源标头 . 因此,请检查 Headers 中是否包含任何 Headers ,是否来自您的域名!如果不拒绝他们 . 如果请求中没有origin和referrer,那么不用担心 . 您可以依赖X-XSRF-TOKEN标头验证结果,我将在下一步中解释 .

    • 虽然浏览器会自动为请求域提供cookie,但有一个有用的限制:网站上运行的JavaScript代码无法读取其他网站的cookie . 我们可以利用它来创建我们的CSRF解决方案 . 为了防止CSRF攻击,我们必须创建一个额外的Javascript可读cookie,称为:XSRF-TOKEN . 必须在用户登录时创建此cookie,并且该cookie应包含随机的,不可猜测的字符串 . 我们还将这个号码保存在JWT本身作为私人索赔 . 每次JavaScript应用程序想要发出请求时,都需要读取此标记并将其发送到自定义HTTP标头中 . 因为这些操作(读取cookie,设置 Headers )只能在JavaScript应用程序的同一个域上完成,所以我们可以知道这是由使用我们的JavaScript应用程序的真实用户完成的 .

    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代表您的用户发出请求 .

    Whether you store your JWT in the localStorage or you store your XSRF-token in not HttpOnly cookie, both can be grabbed easily by XSS. Even your JWT in an HttpOnly cookie can be grabbed by an advanced XSS attack like XST method.

    因此,除了Double Submit Cookies方法之外,您还必须始终遵循针对XSS的最佳实践,包括转义内容 . 这意味着删除任何可能导致浏览器执行您不想要的操作的可执行代码 . 通常,这意味着删除导致JavaScript被评估的 // <![CDATA[ 标记和HTML属性 .

    在这里阅读更多:

相关问题