通过质询/响应保护会话的每个请求



我们需要设计一个安全的Web应用程序。我想提出一种会话处理机制,该机制对每个请求进行质询-响应,而不仅仅是在使用 CRAM 方法登录期间。

原因是强化Web应用程序以防止会话劫持(例如CSRF)和重放或中间人攻击。

在某些地方建议使用nonce,但在我们的Web应用程序中,这似乎不切实际,因为异步请求可以继续,或者用户可以打开新窗口,点击后退按钮等。

想法:客户端和服务器有一个共享的密钥(先前建立的用户密码),每个后续请求都会根据该密钥再次进行质询/响应,例如"响应 = hash(challenge + hashedPassword)"。仅当对质询的响应匹配时,服务器才会执行请求。与 CRAM 期间非常相似,但每个请求都在持续进行。

问题:这是一个可行的想法吗?如果是这样,它肯定已经实施,甚至是一些标准?我们如何在基于 java 或 php 的 Web 应用程序中使用它?

问题实际上归结为您想要实现的目标。如果您想对抗CSRF攻击,除了会话密钥之外,还有一个秘密令牌是您的出路。但是,在每个请求中更改令牌会导致问题 - 不仅后退按钮会终止会话,而且由于一个网页通常包含大量异步和并行加载的数据(图像、css、javascript 等),您的方法将不允许在之后加载任何其他数据,因为每个额外的请求都会更改所需的令牌, 从而杀死会话。

您可以通过 BASE64 和其他技巧将所有资源嵌入页面来解决此问题,但这会严重阻碍您的可能性,并且可能会与某些浏览器存在兼容性问题。

因此,最终,您的方法不会增加太多安全性,但很可能会给您的客户带来一系列潜在问题。我会坚持在URL中的每个会话中使用一个秘密令牌来对抗CSRF,并专注于防止其他攻击,如XSS和用户友好的安全措施,如使用智能手机或类似的东西进行双因素身份验证。毕竟,用户是当今的#1攻击媒介。


更新 (2012-06-14)

令牌不会对抗XSS攻击,但它可以防御基本的CSRF攻击(例如,通过在图像中植入虚假的URL调用)。我今天实际上在工作中遇到了一种情况,我需要保护针对用户修改的 get 请求并编写了一些代码。该代码还可用于保护静态、会话超时formlink令牌(纠正您的问题)。

这个想法是拥有一个服务器密钥,用于在数据上生成哈希/AuthToken以确保安全。如果一个流氓JavaScript试图改变任何给定的数据,AuthToken将不匹配。在我的特定问题中,我有一个服务器对用户进行身份验证,并且必须将他的信息发送给第三方(用户名,邮件地址,名称等)。身份验证后,任何用户都可以轻松更改此 GET-请求,因此我必须对 GET-Request-Parameters 进行身份验证。通过重新运行 AuthenticationToken-Process,第三方可以比较生成的 AuthToken,从而验证传入的数据。如果没有共享密钥,就(几乎)不可能伪造数据。

关于你的问题:在GET和POST请求(或像我的项目这样的动态令牌)上有一个静态令牌,将通过论坛中的链接保护你免受简单的CSRF攻击,用户必须点击这些链接才能受到攻击。由于链接永远不会包含正确的令牌,因此您的网页是安全的。但是,如果攻击者设法通过XSS将javascript加载到网页中,那么您就完蛋了,世界上没有任何技术可以帮助对抗它,因为javascript可以扫描页面的整个DOM树以找到捕获任何令牌。

所以,它归结为:

  • 在GET和POST请求上使用令牌来对抗CSRF
  • 保护您的页面免受 XSS 注入的影响

我发现OWASP备忘单是此类设计决策的良好资源:

  • CSRF预防备忘单
  • XSS 预防备忘单

您的方案听起来类似于 HTTP 摘要式身份验证,无需建立任何类型的会话后身份验证。这可能是对HTTP Basic的改进。这是假设两者都通过TLS!

我不确定您的计划有多可行,或者它有多容易受到重放攻击或 MITM。


如果这是一个选项,您可以考虑新的 <keygen> html5 标记,它可以帮助建立双向 TLS 会话。这将是最安全的选择。

最新更新