【发布时间】:2020-01-16 13:15:16
【问题描述】:
背景
很抱歉这个问题有点开放,但我只是想了解它是如何工作的,而且我是这个领域的新手。
我正在构建一个由 (Apollo) 服务器支持的 SPA。这个问题与使用 JWT Bearer 令牌的传统身份验证有关。我会假设服务器有一个有效的 TLS 证书。
问题
我会先写我理解的,如果我有任何错误,请纠正我。干杯!
用户注册。我们向 SPA 发送带有一些元数据(例如 exp)的访问令牌,并将其存储在 httpOnly(以防止 XSS)、SameSite=strict(以防止 CSRF)、secure(以防止 MITM 攻击)cookie 中。然后,它会随每个身份验证请求一起发送,而无需查询数据库,如果我们将角色/范围附加到 JWT 有效负载,即使是授权也无需查询用户数据库。
第一个问题出现在用户尝试注销时。
问题 1
使用 httpOnly cookie 注销用户的最佳做法是什么? Here 我读到最佳实践是设置两个 cookie,一个没有httpOnly(我猜是相同的内容(JWT)?)并且在服务器身份验证逻辑中都需要。当用户注销时,我们会删除非 httpOnly 的,这会有效地注销用户。
问题 2
如何处理多设备登录?我猜 JWT 没有任何东西来识别设备,所以只需在 cookie 中发出一个新令牌。
到目前为止一切顺利。
现在,假设上述令牌永远不会泄漏,我相信这是一个安全的系统。然而,实际上事情并没有那么简单。有人可以从无人看管的计算机上快速复制 cookie 数据。这甚至可以使用 U 盘脚本来完成,因为 cookie 只是文件系统中的文件。
问题 3
有什么方法可以缓解这种情况?这里还有一些问题,以及我的扶手椅解决方案:)
3.1:浏览器是否有 API 可以安全地加密 cookie?如果是这样,我们可以加密 cookie。我猜他们没有。
3.2:我的整个想法是使用子网掩码和 IP 地址来唯一标识设备。但这可能行不通-我假设子网掩码没有像IP地址这样的http请求中携带,并且在js中执行此操作将受攻击者的支配。最后,这对(IP,子网掩码)不是一个很好的设备标识符,因为在断开连接后,另一个设备可以使用该子网掩码。去他妈的。
3.3:使用短期 JWT。 imo有点hacky解决方案。我们将 JWT exp 设置为 15-30 分钟,并假设在那段时间内,攻击者 can't cause much damage。删除帐户等关键操作仍然需要密码(将通过 https 发送),从而限制了攻击的范围。 15 分钟后,系统将提示用户重新登录并可以恢复所有效果或联系支持人员将其删除。
但是,出现了一个新问题:我们不希望用户必须每 15 分钟登录一次。我的理解到此结束:
3.3.1:使用存储为 cookie 的长期刷新令牌 - 实际上并没有太大变化。
3.3.2:在数据库中使用长期刷新令牌。好吧,看起来很公平。一旦用户在其帐户中发现恶意行为,他们就可以联系支持人员,所有刷新令牌都将被删除,攻击者的剩余时间将少于 15 分钟。实际上,我们只是对是否存在违规感兴趣,所以我们可以使用布尔值;为什么要使用刷新令牌?
恕我直言,问题是攻击者仍然永远可以访问视图。所以我们仍然需要将它与一些设备标识(用户代理、IP 地址...)结合起来,从而引入额外的复杂性。
对于非关键(银行)应用程序来说,似乎最好的解决方案就是使用长寿命访问令牌。我将尝试用两个论点来证明该决定的合理性:
3.3.3:如果有人可以物理访问您的设备,他们通常会做比复制 cookie 更糟糕的事情。
3.3.4:Facebook 似乎使用 6 个月的访问令牌?至少表面上看起来是这样的:我去了 fb.com,删除了我的 c_user cookie,cmd+r,登录,并在 6 个月内创建了一个新的,减去一些更改。但我无法以有效的方式将 cookie 从 Brave 复制到 Chrome。我做错了什么还是有防止此类攻击的实际好方法(无需在每个请求上查询数据库)?
结束
很抱歉,文本很长,但是关于安全性的问题太多且不完整,我只想确保我做的一切都是正确的。如果有人对我写的内容有 cmet 或部分答案,我将非常感激。我很高兴了解这个新的网络安全领域!
【问题讨论】: