CSRF 代币与 Nonce 混淆 - 它们相同吗?
为了使我正在开发的当前应用程序更加安全,我一直在阅读有关 CSRF 令牌和 Nonce 的内容。
我的问题很简单,CSRF 代币和 Nonce 是同一个东西吗?到目前为止我所能收集到的是,这两种方法都有不同的技术来实现相同的目标,或者我是否误解了什么?
如果它们不同,您能否提供一些示例代码或向我指出一些链接,在这些链接中我可以了解有关如何在 PHP 应用程序中实现随机数的更多信息。
谢谢!
In a attempt to make the current application I'm developing more secure, I've been reading about CSRF tokens and also Nonce.
My question simply is, Are CSRF tokens and Nonce the same thing? from what I could gather so far is that both these methods have different techniques to accomplish the same goal, or am I misunderstanding something?
If they are different, could you be nice enough to provide some example code or point me to some links where i can learn more about how to implementing nonces in PHP apps.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,它们不一样。
Nonce 可以防止重播攻击(防止窃听者存储签名的请求并稍后重新提交,例如,如果 Alice 发送“向 Bob 支付 100 美元”,您不希望有人重新发送 100 次)。
CSRF 令牌修补了用户操作身份验证中特定于 HTML 的弱点,其中第 3 方网站可以提交带有用户查看该网站的凭据的表单(例如,使用您的浏览器在 evil.example.com 上提交表单到 facebook.com 上的 JavaScript,并按照您的身份进行身份验证) )。
CSRF 令牌需要保密,否则攻击者将拥有伪造请求所需的缺失部分。
如果随机数是用请求者的秘密签名的,则它们不必是秘密的(只要攻击者不能用另一个随机数替换一个随机数)。
您可以允许使用 CSRF 令牌重播请求,并且仍然能够防范 CSRF(您感兴趣这是否是用户有意执行的操作,但可能不一定希望阻止用户多次执行该操作)。
事实上,这通常是有用的属性,例如允许用户使用“后退”按钮并重新提交具有更正值的表单。如果您使用类似 Nonce 的机制实现 CSRF 保护,那么当用户刷新提交的页面时,您将收到误报。
在没有 Nonce 的情况下防止 CSRF 的一个简单方法是将会话 ID 放在隐藏字段中(不是存储在会话中的值,而是会话本身的 ID,与存储在 cookie 中的相同) PHP 中的
session_id()
])。提交表单后,检查表单的会话 ID 是否与 cookie 中的 ID 匹配。这对于 CSRF 来说已经足够了,因为攻击者无法知道 cookie 的值(CSRF 只允许攻击者盲目发送 cookie)。No, they're not the same.
Nonces prevent replay attacks (prevent eavesdropper from storing signed request and re-submitting it later, e.g. if Alice sends "Pay Bob $100", you don't want somebody to re-send that 100 times).
CSRF tokens patch HTML-specific weakness in authentication of users' action, where 3rd party website can submit forms with credentials of user viewing the site (e.g. JavaScript on evil.example.com submitting form to facebook.com using your browser, authenticated as you).
CSRF tokens need to be secret, otherwise attacker would have the missing piece required to forge a request.
Nonces don't have to be secret if they're signed with requester's secret (as long as attacker cannot replace one nonce with another).
You can allow replay of requests with CSRF tokens and still be secured against CSRF (you're interested whether that was intentional action by the user, but may not necessarily want to stop user from performing it many times).
In fact, that's very often useful property, e.g. allows users to use Back button and re-submit forms with corrected values. If you implement CSRF protection with Nonce-like mechanism, you'll get false alarms when users refresh submitted pages.
An easy way to prevent CSRF without Nonces is to put session ID in a hidden from field (not a value stored in the session, but ID of the session itself, the same that you store in the cookie [
session_id()
in PHP]). When the form is submitted check that form's session ID matches ID in the cookie. That is enough for CSRF, since attacker cannot know value of the cookie (CSRF only allows attackers to blindly send cookies).Nonce 通常是添加到请求中的一些随机字符串,只是为了以不可预测的方式更改数据,用于计算签名。因此,任何服务器端业务逻辑通常不使用随机数。
而CSRF-token存储在服务器上的某个位置,传递给客户端并需要返回到服务器进行比较。如果匹配 - 则确定。
因此,在您的情况下,最好将 csrf 令牌保存在会话变量中一次
,并在会话生命周期内以应用程序中的所有形式不加更改地使用它。
(如果您没有
random_bytes()
,请使用 random_compat 来填充它.)Nonce is usually some random string that is added to request just to change in unpredictable way the data, which is used to calculate the signature. So nonce usually is not used by any server-side business logic.
While CSRF-token is stored somewhere on server, passed to the client and need to be returned back to the server to compare. And if matches - then OK.
So in your case the better will be to save csrf token once in a session variable like
and use it unchanged during the session life in all forms you have in your application.
(If you don't have
random_bytes()
, use random_compat to polyfill it.)这有点像同一件事。 “随机数”本身只是一个一次性密码。它可以充当加密盐,但基本上只是一个随机值。请参阅 WP:Nonce
但总而言之,随机数经常被使用作为 CSRF 令牌。这是一个实施细节。与其他用例的区别在于它稍后被断言。
It's sort of the same thing. A "nonce" is just a one-time password itself. It can serve as cryptographic salt, but basically is just a random value. See WP:Nonce
But to sum it up, a nonce is often used as CSRF token. It's an implementation detail. The difference to other use cases is that it later gets asserted.
CSRF 有一些限制。
如果您有要求在新选项卡中打开任何页面或链接,则 CSRF 将不允许。现有令牌仅允许在新选项卡中打开页面 5 次。
当您尝试第六次打开时,它将创建与“服务器端 = 客户端令牌”不匹配的新令牌。较早的令牌将过期,并且将创建新的令牌(NONCE),在这种情况下,您将收到 404 或 405 错误。
CSRF having some limitation.
in case if you have requirement where you want to open any page or link in new tab then CSRF won't allow. existing token will allow to open page in new tab for 5 times only.
when you will try to open 6th time it will create the new token which will not match with "server side = client side token". earlier token will expire and new token(NONCE) will create, in that case you will get 404 or 405 error.