只要浏览器处于打开状态就可以让会话保持打开状态,这就是自动攻击的问题.不幸的是,刷新每个页面加载的令牌只会阻止大多数业余攻击者.
首先,我假设我们正在讨论专门针对您网站的攻击. (如果我们谈论的是那些只是漫游并提交各种形式的机器人,这不仅会阻止它们,而且还有更好,更简单的方法.)如果是这样的话,那我就是针对我的网站,这是我的机器人会做的事情:
>加载表单页面.
>在表单页面上读取令牌.
>使用该令牌提交自动请求.
>转到第1步.
(或者,如果我对你的系统进行了足够的调查,我会意识到,如果我在每个请求中包含“这是AJAX”标头,我可以永久保留一个令牌.或者我会意识到令牌是我的会话ID,并且发送我自己的PHPSESSID cookie.)
这种在每个页面加载时更改令牌的方法绝对不能阻止那些真正想要攻击你的人.因此,由于令牌对自动化没有影响,请关注其对CSRF的影响.
从阻止CSRF的角度来看,创建一个令牌并维护它直到用户关闭浏览器似乎可以实现所有目标.简单的CSRF攻击失败,用户可以打开多个选项卡.
TL; DR:每次请求刷新令牌一次不会提高安全性.寻求可用性并在每个会话中执行一个令牌.
然而!如果您非常担心重复的表单提交,无论是意外还是其他方式,这个问题仍然可以轻松解决.答案很简单:对两个不同的工作使用两个令牌.
第一个令牌将保持不变,直到浏览器会话结束.此令牌用于防止CSRF攻击.此用户使用此令牌提交的任何内容都将被接受.
第二个令牌将为每个加载的表单唯一生成,并将存储在用户打开表单令牌的会话数据的列表中.此令牌是唯一的,一旦使用就会失效.此用户使用此令牌提交的内容将被接受一次且仅一次.
这样,如果我打开表格A的标签和表格B的标签,每个人都有我的个人反CSRF令牌(CSRF照顾),以及我的一次性表格令牌(表格重新提交照顾).解决这两个问题对用户体验没有任何不良影响.
当然,你可能会认为实现这么简单的功能太过分了.无论如何,我认为它是.无论如何,如果您需要,都可以使用可靠的解决方案.