为了防止 CSRF 攻击,您应该在表单中的隐藏字段和 cookie 或会话变量中放置一个 nonce。但是,如果用户在不同的选项卡中打开了几个页面呢?在这种情况下,每个选项卡都会使用唯一的 nonce 填充表单,但是会话变量或 cookie 中只有一个 nonce。或者,如果尝试将所有 nonce 存储在 cookie/session 变量中,又如何确定哪个 nonce 属于哪个表单呢?
有些人为每个表单生成一个令牌,这是一种非常安全的方法。然而,这可能会破坏您的应用程序并惹恼用户。为了防止对您的站点进行所有XSRF攻击,您只需要为每个会话设置唯一的1个令牌变量,然后攻击者将无法伪造任何请求,除非他能找到这1个令牌。这种方法的小问题是,只要受害者访问攻击者控制的网站,攻击者就可以暴力破解此令牌。但是,如果令牌相当大,例如32字节左右,则需要很多年才能暴力破解,并且http会话在那之前应该已经过期。
很久以前写了这篇文章。 我已经实现了一个几乎可以保护的csrf阻止器。 它可以在多个打开的窗口中运行,但我仍在评估它所提供的保护类型。它使用DB方法,即将存储到表而不是会话。 注意:在这种情况下,我使用MD5作为一种简单的反SQLi机制。
伪代码:
表格:
token = randomstring #to be used in form hidden input
db->insert into csrf (token, user_id) values (md5(token),md5(cookie(user_id))
——令牌将被保存在数据库中,直到从下面的操作脚本中访问:
操作脚本:
if md5(post(token)) belongs to md5(cookie(user_id))
#discard the token
db -> delete from csrf where token=md5(post(token)) and user_id=md5(cookie(user_id))
do the rest of the stuff