Php CSRF令牌-如何正确实施?

Php CSRF令牌-如何正确实施?,php,security,csrf,Php,Security,Csrf,我刚刚在我的应用程序中设置了一个简单的CSRF保护。它创建一个独特的crump,在提交表单时根据会话值进行验证 不幸的是,这意味着现在我无法在CSRF碎屑相互碰撞时同时打开应用程序的多个实例(浏览器中的选项卡) 我应该为每个实际的表单创建一个单独的令牌,还是为我的所有表单使用一个共同的、共享的面包屑? 这里的常识是什么 据我所知,您可以使用 1)随机数并将其保存到会话中: 将其添加到名为hidden的隐藏输入中,然后当您收到信息时,可以使用会话值检查隐藏字段 2)静态配置变量(与前面的会话相同,

我刚刚在我的应用程序中设置了一个简单的CSRF保护。它创建一个独特的crump,在提交表单时根据会话值进行验证

不幸的是,这意味着现在我无法在CSRF碎屑相互碰撞时同时打开应用程序的多个实例(浏览器中的选项卡)

我应该为每个实际的表单创建一个单独的令牌,还是为我的所有表单使用一个共同的、共享的面包屑?
这里的常识是什么

据我所知,您可以使用

1)随机数并将其保存到会话中:
将其添加到名为hidden的隐藏输入中,然后当您收到信息时,可以使用会话值检查隐藏字段

2)静态配置变量(与前面的会话相同,但没有会话)
隐藏字段将包含此值(配置中的变量)。验证时,您将检查隐藏的密码和配置安全密钥值

3)HTTP参考程序
您可以使用http Referer来了解用户来自何处,然后使用实际域进行检查(如果您的网站包含xss,则此方法可能会进行攻击)

据我所知,您可以使用任何解决方案:)

对这类问题有最明确的答案。它讨论了不同的方法以及安全性与可用性之间的平衡


简言之,他们建议每个(浏览器)会话使用一个令牌。换句话说,在您的情况下,相同的令牌在选项卡之间共享。备忘单还强调,不要让站点暴露于跨站点脚本漏洞非常重要,因为这会破坏每会话CSRF令牌策略。

您也可以这样做。这取决于您想要的安全级别

OWASP企业安全API(ESAPI)使用单令牌每用户会话方法。假设您没有XSS漏洞,并且会话超时很短,那么这可能是一种非常有效的方法。如果允许会话持续几天或几周,那么这不是一个好方法

就我个人而言,我并不觉得为每个表单的每个实例使用不同的令牌有什么困难。我使用键值对在用户会话中存储结构。每个项的键是表单的ID,值是另一个包含令牌和该令牌的到期日期的结构。通常,我只允许令牌生存10-20分钟,然后它就会过期。对于较长的表格,我可能会给它一个较长的到期时间


如果您希望能够在同一会话中在多个浏览器选项卡中支持同一表单,那么我的方法会变得有点诡计,但仍然可以通过使用唯一的表单ID轻松完成

你的第二个例子;您如何建议使用静态变量作为CSRF令牌?代币背后的整个理念是它们的独特性,这意味着没有人能够事先猜到代币是什么。这究竟是如何使任何形式更安全的呢?2不起作用,因为密钥不是每个用户一个的。3是不推荐的,因为很多公司的防火墙都会去掉referer头,而且它确实不可靠。HTTP referer不是击败CSRF的安全方法。(两者都不是静态变量。)@Industrial:我不是指静态变量,我指的是配置信息$csrf=''之类的变量;//请将其更改为您喜欢的任何单词,我在admin中谈到csrf,因此没有人能够知道该单词是可变的和隐藏的,因此当攻击者重定向用户添加admin时,他将要求隐藏字段->来自配置,因为用户验证码可以执行此任务,我并不是说在所有站点中都是静态的,只要编辑config的值,变量就可以随时更改为任何单词,我告诉http referer,如果你的网站包含xssy,你的意思是,每个表单的每个实例都有自己的令牌?例如,
?我认为,只要您不通过http(仅https)提交令牌,每个会话使用一个令牌是合理的。它们与会话ID有许多安全问题。如果你有XSS,攻击者可以打开iFrame,读取令牌,并执行CSRFs。如果你有XSS,你已经丢失了。附加的每个表单的nonce不会保存您(攻击者将能够获得一个新表单,使用新的nonce,填写并提交,就像用户所做的那样)。每个用户的单个值对于CSRF来说绝对足够了。