CSRF令牌与Nonce混淆 - 它们是一样的吗?
为了使我正在开发的当前应用程序更加安全,我一直在阅读有关CSRF令牌和Nonce的信息。
我的问题是,CSRF代币和Nonce是一回事吗?到目前为止,我能收集到的是,这两种方法都有不同的技术来实现相同的目标,还是我误解了什么?
如果它们不同,你能不能提供一些示例代码或指向我一些链接,我可以在其中了解有关如何在PHP应用程序中实现nonce的更多信息。
谢谢!
为了使我正在开发的当前应用程序更加安全,我一直在阅读有关CSRF令牌和Nonce的信息。
我的问题是,CSRF代币和Nonce是一回事吗?到目前为止,我能收集到的是,这两种方法都有不同的技术来实现相同的目标,还是我误解了什么?
如果它们不同,你能不能提供一些示例代码或指向我一些链接,我可以在其中了解有关如何在PHP应用程序中实现nonce的更多信息。
谢谢!
不,它们不一样。
Nonces可以防止重放攻击(防止窃听者存储签名的请求并在以后重新提交,例如,如果Alice发送“向Bob支付100美元”,您不希望有人重新发送100次)。
CSRF令牌修补了用户操作身份验证中特定于HTML的弱点,其中第三方网站可以使用用户查看网站的凭据提交表单(例如,evil.example.com 使用浏览器向 facebook.com 提交表单的JavaScript,以您的身份进行身份验证)。
CSRF令牌必须是秘密的,否则攻击者将拥有伪造请求所需的缺失部分。
如果 Nonces 是用请求者的密钥签名的,则它们不必是秘密的(只要攻击者不能用一个 nonce 替换另一个随机数)。
您可以允许使用CSRF令牌重放请求,并且仍然可以针对CSRF进行保护(您感兴趣的是否是用户的故意操作,但可能不一定希望阻止用户多次执行它)。
实际上,这通常是非常有用的属性,例如,允许用户使用“后退”按钮并重新提交具有更正值的表单。如果您使用类似Nonce的机制实施CSRF保护,则当用户刷新提交的页面时,您将收到误报。
防止没有Nonce的CSRF的一种简单方法是将会话ID放在隐藏的for字段中(不是存储在会话中的值,而是会话本身的ID,与您存储在cookie中[在PHP中]中的ID相同)。提交表单后,请检查表单的会话 ID 是否与 Cookie 中的 ID 匹配。这对于CSRF来说已经足够了,因为攻击者无法知道cookie的价值(CSRF只允许攻击者盲目地发送cookie)。session_id()
Nonce通常是一些随机字符串,它被添加到请求中,只是为了以不可预测的方式更改数据,用于计算签名。因此,nonce 通常不被任何服务器端业务逻辑使用。
而CSRF令牌存储在服务器上的某个位置,传递给客户端并需要返回给服务器进行比较。如果匹配 - 那么OK。
因此,在您的情况下,最好是在会话变量中保存一次csrf令牌,例如
$_SESSION['csrf_token'] = bin2hex(random_bytes(16));
并在会话期间以您在应用程序中拥有的所有形式原封不动地使用它。
(如果没有 ,请使用 random_compat 来填充它。random_bytes()