安全的单站点 JWT 实施
Posted
技术标签:
【中文标题】安全的单站点 JWT 实施【英文标题】:A secure single site JWT implementation 【发布时间】:2021-04-15 17:21:50 【问题描述】:我阅读了很多关于 JWT 的文章,发现很难以安全的 CSRF 和 XSS 证明方式使用它们。 直到我意识到我的令牌可能不会离开我的唯一域...... 这让我想到了实现的想法:
-
使用刷新令牌和访问令牌。这样,我可以为访问令牌设置较短的过期时间并限制数据库调用以验证用户,并且仅在访问令牌过期时通过询问数据库刷新令牌未列入黑名单,然后再将新的访问令牌发送到用户。
我知道,如果我将令牌存储在本地/会话存储中,它将容易受到 XSS 攻击,但如果我将其存储在仅 HTTP 的 cookie 中,则会容易受到 CSRF 攻击。
由于我不需要访问 javascript 中的令牌并且我只需要在一个网站中使用此令牌,我认为我可以将访问令牌存储在仅 HTTP 的 cookie 中(这样就可以防止 XSS ) 以及设置为严格的安全标志和相同的站点标志(防止 CSRF)。
关于刷新令牌,我可以将其存储在具有相同安全标志但这次没有相同站点标志的仅 HTTP cookie 中。因为服务器永远不会仅基于刷新令牌执行任何操作,我认为它因此不会受到 CSRF 攻击。服务器对刷新令牌唯一要做的就是发回一个新的访问令牌,如果我理解得很好,CSRF 攻击者无法读取该令牌。 CSRF 漏洞允许攻击者向服务器发出请求(服务器将自动包含仅 HTTP cookie),但他无法读取该请求的响应。
我不知道 JWT 的这种实现是否安全,或者我是否遗漏了什么......
这就是我要问您(JWT 和网络安全专家)的问题,这会是一个好的 JWT 实施吗?
【问题讨论】:
我认为您只需要一个带有服务器端会话的普通旧会话 ID。 JWT 对您的用例的好处几乎为零,但复杂性无助于安全性。 【参考方案1】:首先,谈谈 JWT。在大多数情况下,老式的普通服务器端会话(具有长的随机会话 id,正确存储在安全的 httpOnly 中,也可能是 SameSite cookie)比任何 JWT 都“更安全”。原因是 JWT 将状态存储在客户端,攻击者更容易使用它,离线攻击可以针对所涉及的加密技术执行,JWT 也是纯文本,只有它们的完整性受到保护(即它们受到保护侧面改变,但不反对默认查看内容,尽管您可以使用 JWE,也可以使用加密的 JWT)。最后但并非最不重要的一点是,实现更加复杂,而简单性对安全性非常重要。
因此,当您需要 JWT 提供的好处时,您可以使用它。
一个论点是它是无状态的。不过,这经常被高估。首先,在大多数应用程序中,瓶颈不是在数据库中查找会话数据所需的数据库查找。在一些非常高调、高流量的应用程序中,它实际上可能是这样,但您可能不会每天都在开发类似的东西。通常进行数据库查找就可以了,它使整个事情变得简单得多。其次,有时您需要撤销令牌,即。您希望能够强制注销用户。即使您将 JWT 用于无状态,您也必须将 something 存储在数据库中,例如已撤销令牌的列表,并且检查这也将是数据库往返。撤销 JWT 根本无法以纯粹的无状态方式实现。
另一个好处是您可以将它用于多个来源。如果您获得一个由浏览器管理的 httpOnly 会话 cookie,则 javascript 无法将其发送到其他来源,例如 API 或其他东西 - 这就是重点,JS 无法访问。但有时您确实需要这样做,尤其是在单点登录场景中,您有一个身份提供者(一个提供登录的组件)和您想要在其上使用访问令牌的服务(例如 API)。在这种情况下,经典 cookie 将不起作用,而 JWT 非常方便。
因此,简而言之,当您确实需要无状态或将令牌发送到多个来源的选项时,您会使用 JWT。根据经验,如果您可以将 JWT 存储在 httpOnly cookie 中,那么您很可能根本不需要它,只需使用普通的旧服务器端会话即可。
然后假设您决定使用 JWT,那么刷新令牌呢?它们是基于令牌的身份验证的另一个通常被误解的功能。使用刷新令牌的目的是能够使用短期访问令牌,因此如果访问令牌被泄露,它至少是有时间限制的。但是,如果您以与访问令牌相同的方式存储刷新令牌,为什么攻击者也无法获得呢?
只有拥有一个刷新令牌才有意义,如果你以不同的方式存储它,否则你可能只拥有长期存在的访问令牌,而且不会降低安全性。
一个典型的事情是有一个身份提供者(“登录服务器”或 IdP)在身份提供者来源的 httpOnly cookie 中设置一个刷新令牌(或只是一个普通的旧会话 id),所以每当客户端对 IdP 的请求,如果他们已经登录,它“就可以工作”,并且可以在没有用户交互的情况下提供新的访问令牌。然后,访问令牌存储在类似 localStorage(用于服务源)中,易受 XSS 影响,但至少有时间限制。如果没有这种分离,单独的刷新令牌可能没有多大意义。
最后一点,所有这些都应该很少由您自己实现。您使用的任何语言或框架可能已经具有一个或多个已知的良好、维护的身份验证实现。您应该只使用它们,但当然仍然非常值得了解它。
请注意,在任何实际应用中,可能存在细微之处和某些情况会在一定程度上改变您想要做的事情,但以上是考虑安全身份验证的一般方式。
【讨论】:
非常感谢!你是对的,我应该使用会话......我被 JWT 的无状态的一面所吸引,但由于我需要撤销它是不值得的......最重要的是,运行一个 db 的成本可能并不高查询每个请求。以上是关于安全的单站点 JWT 实施的主要内容,如果未能解决你的问题,请参考以下文章
[安全设置] 防范网页挂马攻击 从对WEB站点进行安全评估开始红盟安全
[安全设置] 防范网页挂马攻击 从对WEB站点进行安全评估开始红盟安全