问题实际上归结为您想要实现的目标。如果你想对抗 CSRF 攻击,除了会话密钥之外的秘密令牌是你的方法。但是,在每个请求中更改令牌会导致问题 - 不仅后退按钮会终止会话,而且由于一个网页通常包含大量异步和并行加载的数据(图像、css、javascript 等),因此您的方法之后将不会加载任何其他数据,因为每个额外的请求都会更改所需的令牌,从而终止会话。
您可以通过 BASE64 和其他技巧将所有资源嵌入到页面中来解决此问题,但这会严重阻碍您的可能性,并且可能与某些浏览器存在兼容性问题。
因此,最终,您的方法不会增加太多安全性,但很可能会给您的客户带来一整套潜在问题。我会在 URL 中的每个会话中使用一个秘密令牌来对抗 CSRF,并专注于保护其他攻击,例如 XSS 和用户友好的安全措施,例如使用智能手机或类似的东西进行双因素身份验证。毕竟,用户是当今排名第一的攻击媒介。
更新 (2012-06-14)
该令牌不会对抗 XSS 攻击,但它会防御基本的 CSRF 攻击(例如,通过在图像中植入虚假的 url 调用)。实际上,我今天在工作中遇到了一种情况,我需要保护一个 get-request 以防止用户修改并编写一些代码。该代码还可用于保护静态、会话超时form
和link
令牌(解决您的问题)。
这个想法是有一个服务器机密,用于在数据上生成哈希/AuthToken以保护。如果流氓 javascript 尝试更改任何给定数据,则 AuthToken 将不匹配。在我的具体问题中,我有一台服务器对用户进行身份验证,并且必须将他的信息发送给第三方(用户名、邮件地址、姓名等)。此 GET-Request 可能会在身份验证后被任何用户轻松更改,因此我必须对 GET-Request-Parameters 进行身份验证。通过重新运行 AuthenticationToken-Process,第三方可以比较生成的 AuthToken,从而验证传入的数据。如果没有共享的秘密,就(几乎)不可能伪造数据。
关于您的问题:在 GET 和 POST 请求上使用静态令牌(或像我的项目一样的动态令牌)将保护您免受简单的 CSRF 攻击,例如通过论坛中的链接,用户必须单击才能受到攻击。由于链接永远不会包含正确的令牌,因此您的网页是安全的。但是,如果攻击者设法通过 XSS 将 javascript 加载到网页中,那么你就完蛋了,世界上没有任何技术可以帮助对付它,因为 javascript 可以扫描页面的整个 DOM 树以找到捕获任何令牌任何。
所以,归结为:
- 在 GET 和 POST 请求上使用令牌来对抗 CSRF
- 保护您的页面免受 XSS 注入