首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >安全地使用带有CSRF保护和刷新令牌的JWT

安全地使用带有CSRF保护和刷新令牌的JWT
EN

Security用户
提问于 2016-08-12 23:49:10
回答 3查看 14K关注 0票数 14

我正在我的应用程序中实现JWT,我希望使它们尽可能安全。我将列出我所计划的一切,我将非常感谢关于这个实现的安全性的任何建议。这是我的网站,我有充分的访问它的每一个方面,前端和后端。

这将是一个SPA,使用API访问后端.我使用JWT来保存每次命中API时的DB调用。

JWTs

JWT存储在access_token cookie中。它们首先进行签名,然后使用何塞-杰沃特加密。签名算法为HS256,加密为DIR。它们包括用户ID、过期exp声明和其他几个自定义声明。JWT在30分钟内到期,JWT cookie在7天内到期。

(简写):

  • 存储在cookie中的JWT
  • JWT包括用户ID
  • JWT签名后加密
  • JWT exp索赔在未来设置为30分钟
  • JWT cookie将在未来7天内到期

CSRF保护

JWT包括一个存储随机生成的CSRF令牌的cst声明。CSRF令牌在登录和发布新的JWT时在响应体中发送。CSRF令牌存储在浏览器的localStorage中。它与每个请求一起发送,并根据JWT中的值进行验证。

(简写):

  • JWT包括随机生成的CSRF令牌。
  • 登录时发送并存储在localStorage中的CSRF令牌
  • 在所有请求的请求头中发送CSRF令牌
  • JWT中的头CSRF令牌与CSRF令牌的比较

刷新令牌

由于JWT在30分钟内到期,因此有必要刷新它们。JWT包括一个存储随机刷新令牌的rfs声明。此刷新令牌还存储在DB中(这是一个独立于用户的表,允许进行多个会话)。如果JWT过期(基于其exp声明),将检查DB以确保用户仍然有效(例如帐户未删除、密码未更改等)。如果用户有效,则对刷新令牌进行验证,生成一个新的JWT/CSRF令牌并在响应中传回。如果用户无效,access_token将被发送回任意值,如0,其过期设置为过去,因此浏览器将清除它。CSRF令牌是空的,因此它将从localStorage中清除。用户的所有刷新令牌都从DB中清除。

(简写):

  • 如果JWT过期,请检查用户DB以验证用户是否仍然有效。
  • 如果有效:
    • 将刷新令牌与DB进行比较(假设与其馀部分匹配)
    • 生成新的刷新令牌,在DB中覆盖以前的值。
    • 用新的exp日期重新发布JWT
    • 将刷新令牌传回并存储在localStorage中

  • 如果无效:
    • 将JWT cookie清除为( a)设置为无效值,( b)将过期设置为过去
    • 告诉浏览器清除localStorage CSRF令牌
    • 从DB中为用户清除所有刷新令牌

快速而肮脏的TL;

博士

  • 登录时,向JWT添加一个随机CSRF令牌。
  • 将相同的CSRF令牌发送回响应体中的客户端。
  • 将CSRF令牌存储在localStorage中。
  • 在JWT中包含一个刷新令牌。
  • 将JWT cookie设置为在1周后过期。
  • 将JWT exp声明设置为30分钟。
  • 如果JWT声明过期,请验证针对DB的刷新令牌,以确保用户仍然有效。
  • 如果用户有效:
    • 使用新的CSRF令牌和新的刷新令牌发出更新的JWT。
    • 将JWT cookie的到期时间设置为以后的一周。(基本上,重新发布cookie )
    • 在响应体中发送新的CSRF令牌,覆盖现有的localStorage值。

  • 如果用户无效:
    • 返回同名但没有内容的JWT cookie。
    • 将cookie过期设置为过去的任意日期。
    • 告诉浏览器清除localStorage值。
EN

回答 3

Security用户

发布于 2016-08-21 19:26:43

你似乎混淆了几种不同的对立技术,不清楚为什么你选择了这些技术,为什么它们控制着你想要防范的威胁。

JWT存储在access_token cookie中。它们首先进行签名,然后使用jose-jwt加密。

有什么理由要加密吗?当您想要验证数据的完整性时使用签名--也就是说,没有密钥的任何人都不会修改它。当您想要保护数据的机密性时,使用加密--也就是说,没有密钥的任何人都无法读取它。如果令牌中没有任何东西不能被最终用户读取,那么就没有理由加密。

JWT包括一个cst声明,它存储随机生成的CSRF令牌。CSRF令牌在登录和发布新的JWT时在响应体中发送。CSRF令牌存储在浏览器的localStorage中。它与每个请求一起发送,并根据JWT中的值进行验证。

这听起来像是双提交Cookie CSRF控件的实现。localStorage受同一原产地政策保护,防止用户浏览器中的另一个web会话访问令牌。

确保CSRF令牌至少有128位熵。

由于JWT在30分钟内到期,因此有必要刷新它们。JWT包含一个rfs声明,它存储随机刷新令牌。此刷新令牌还存储在DB中(这是一个独立于用户的表,允许进行多个会话)。如果JWT过期(基于其exp声明),则检查DB以确保用户仍然有效(例如,帐户未被删除,密码未更改等)。如果用户有效,则对刷新令牌进行验证,生成一个新的JWT/CSRF令牌并在响应中传回。

这就是事情变得混乱的地方。您的安全模型应该决定客户端会话还是服务器端会话。JWT通常用于前者。也就是说,如果客户端中有一个令牌,该令牌仅由服务器可用的密钥签名,那么您的应用程序应该相信,如果该令牌未过期,并且该签名是有效的,则此令牌的存在表示有效会话。

这种方法的缺点是很难撤销令牌。如果用户帐户被破坏,用户更改密码,则任何攻击者会话仍将活动30分钟,因为它们仍然具有有效、未过期和签名的令牌。

解决方法是实现服务器端会话。例如,跟踪数据库表中的会话,这意味着可以通过删除数据库中的行立即注销会话。会话令牌可以是128位熵随机字符串,作为cookie客户端提供,并存储在SHA-256服务器端,以减少数据库中的任何数据泄漏。您可以始终使用cookie发送纯文本过期日期,以便客户端知道何时需要刷新令牌。例如,令牌的HttpOnly cookie,以及包含到期的非HttpOnly cookie,以便客户端JavaScript能够读取它。HttpOnly cookies可以帮助减轻XSS缺陷的影响。

因此,如果您正在跟踪会话服务器端,那么拥有一个签名的JWT客户端几乎没有什么好处。额外的代码意味着更多的攻击表面和更多的漏洞被引入多余的代码。应用程序中的复杂性通常与安全性相反。

如果您将双提交Cookie与服务器端会话结合用于会话状态,则明智的做法是为CSRF令牌使用不同的cookie。这将使您能够使用客户端代码将CSRF令牌添加为报头,而无需冒会话标识符令牌的风险。注意,如果您正在设置自定义标头而不是实现CORS,那么这可以在一定程度上减轻CSRF.。不过,还建议使用令牌,因为Flash之类的技术往往会破坏浏览器的安全性(Flash意味着更多代码运行,更多代码提供更多攻击面,更多代码意味着更多漏洞)。

票数 15
EN

Security用户

发布于 2017-12-06 02:18:26

这听起来相当不错( CSRF解决方案也很可爱),直到刷新令牌部分。

我在基于JWT的系统中看到的优点之一是访问令牌定期过期。这意味着受损的JWT访问令牌只允许攻击者进行几分钟或几小时的访问。

如果将Refresh令牌包含在JWT中,那么破坏JWT的攻击者可以很容易地使用它来刷新自己,从而使其没有有效的过期日期。

访问令牌不应该能够授予新的访问令牌。只有刷新令牌(或完全身份验证)才能授予新的访问令牌.

票数 5
EN

Security用户

发布于 2016-08-21 18:05:45

从评论中汇总:

  • JWT作为单一页面应用程序中的承载凭证,通过ajax与服务器端API进行对话是有意义的。
  • 在单个页面应用程序中使用cookie是没有意义的。如果通过ajax函数对服务器API瓶颈的所有请求,该函数可以将JWT包含在标头中。如果没有cookie,那么就没有CSRF,因为来自攻击帧的请求不会通过ajax函数。
  • 当然,第三方脚本的使用是普遍的,但它仍然是一个很大的安全风险。第三方脚本在相同的javascript和DOM上下文中运行,可以看到整个DOM。如果他们是恶意的,有很多,很多攻击选项。如果可能的话,删除第三方脚本或确保它们被验证,使用子资源完整性或其他一些方法(例如,监视它们的变化)。
  • localStorage遵循相同的起源策略,可以将其视为DOM或授权数据的客户端缓存。在SPA中,JWT可以保持在localStorage中,因为它遵循与DOM相同的安全模型。
  • 可以在JWT中保留刷新令牌。
  • JWT过期和刷新生命周期很难在抽象中进行注释。重要的是要在安全性和可用性之间找到正确的平衡,不要要求用户跳槽,除非有充分的理由,而且如果用户有顾虑,也要为他们提供正确的保证。

还有一些其他的事情要做:

  • 强制使用https,并使用相关的资源协议头(如x帧选项、严格传输安全性和内容安全策略)。
  • 在JWT中保留单个Page App特定版本的一些元数据,并需要更新以下应用程序
  • 将特定客户端的元数据保存在JWT中。不允许从移动浏览器中使用桌面浏览器JWT。
  • 能够从服务器撤消与用户关联的所有未完成的JWT和刷新令牌。如果用户将JWT和刷新令牌绑定到他们的手机和桌面上,并告诉您他们丢失了手机,那么您可能想要使他们的手机和桌面JWT以及刷新令牌失效。
  • 在服务器API上拥有强大的对象/操作级授权--也就是说,验证JWT的完整性,确认它包中的授权没有被撤销,然后在执行任何API操作之前检查它包含的声明是否提供了对API的适当访问。
票数 3
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/133787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档