在过去的几天里,我一直在阅读关于这个问题的所有资料,我无法决定什么才是最好的方法。
唯一的两项要求是:
起初,我使用会话cookie,并使用setCredentials=true调用API,但我发现移动应用程序处理cookie的方式不同,而且我无法控制它(例如,在过期之前,由于各种原因,它们会被删除)。我考虑将cookie保存在本机存储中,并将其附加到每个请求中,但我无法以任何方式访问cookie,因为httpOnly设置为true。解决方案是将httpOnly设置为false,但是这样我就暴露了cookie,并且我不确定我应该采取什么安全措施来保护cookie不被窃取或篡改。
另一种解决方案是使用JWT并将其存储在web/本机存储中。我还会将仍然有效的每个令牌(使用密码算法进行散列)存储在表中,以获取登录用户及其会话的列表,以及当用户选择结束某个特定会话/更改密码/等等时,另一个用于无效令牌的表。但同样,我不确定使用这种方法应该采取哪些安全措施。我也应该加密令牌吗?我正在考虑在它后面附加关于请求令牌的设备的数据,始终检查请求令牌的设备是否是使用令牌的设备。我还应该做什么来保护这个标记呢?
如果我正确地实现了这两个选项中的任何一个,那么哪个选项对网络和移动设备都更安全呢?
发布于 2018-10-12 07:39:40
在详细介绍之前,我将说会话cookie和JWT都适用于您的情况,如果实现正确,两者都是安全的。就我个人而言,我会使用JWT,如果只是因为它更容易获得最新信息或现成的解决方案。
JWT实际上是为无状态授权而设计的,但您仍然可以将它们用于会话。您将特别注意使用访问/刷新令牌模型,在该模型中跟踪数据库中的活动刷新令牌。
至于加密,JWT标准有两个主要的实现,即JWS (签名令牌)和JWE (签名然后加密令牌)。您要记住的是,签名令牌的签名已经确保了令牌的完整性。只有在您还将敏感信息传递到您希望从客户端隐藏的令牌中时,才会实现JWE。然而,JWT本身并不能解决中间人攻击的问题,因此您应该记住,每当传输令牌时都要使用SSL。
令牌的存储将在您的web应用程序和移动本地应用程序之间有所不同。对于移动应用程序,您应该将它们存储在操作系统的Keychain/Keystore (很可能是通过包装器)中,这正是为此目的而设计的。另一方面,在浏览器上存储JWT的位置仍然是一个颇有争议的话题,因为在webstorage中存储(sessionStorage/localStorage)容易受到XSS的攻击,而存储在cookie中的攻击则容易受到CSRF的攻击。
据我所知,总的趋势是避免使用webstorage,因为它的攻击面更大,但老实说,我已经看到了这两种方法的例子。对于单页应用程序,您还可以考虑将令牌保存在内存中,而不需要持久存储。
如果不知道移动应用程序的细节,就很难说了,但根据我的经验,如果您使用的是由Google/iOS提供的CookieManager/NSHTTPCookieStorage机制,那么您所描述的删除cookie就不会出现问题。
在浏览器上存储cookie将要求您保护它不受CSRF的影响。对于您应该使用的保护,它将在很大程度上取决于您特定的服务器实现和限制,我认为您应该查看OWASP上的资源,或者问一个更具体的问题。
发布于 2018-10-10 18:51:42
你信任你所有的客户代码吗?如果是,您可以将会话ID存储在本地存储中,并确保将它们与每个HTTP请求一起提交。在后端,只需有一个表,其中会话ID哈希作为主键,用户ID作为外键,以及过期时间。不要保留已删除会话的列表,只需删除该行(或将其标记为已删除)。
cookies的风险在于,它们与每个HTTP请求一起发送到您的域,即使它来自虚假的客户端。这叫做CSRF。除非您有某种CSRF保护,否则请避免使用cookie并使用本地存储。
当然,如果您不能信任所有客户端代码,那么您将需要另一个解决方案。
另外,如果您使用HTTPS,则会话if,无论是cookie还是表单提交,都将被加密。
https://security.stackexchange.com/questions/195474
复制相似问题