18

为了使我正在开发的当前应用程序更安全,我一直在阅读有关 CSRF 令牌和 Nonce 的信息。

我的问题很简单,CSRF 令牌和 Nonce 是一回事吗?到目前为止,我可以收集到的是,这两种方法都有不同的技术来实现相同的目标,还是我误解了什么?

如果它们不同,您能否提供一些示例代码或指向一些链接,我可以在其中了解有关如何在 PHP 应用程序中实现 nonce 的更多信息。

谢谢!

4

4 回答 4

17

不,它们不一样。

随机数防止重放攻击(防止窃听者存储签名请求并在以后重新提交,例如,如果 Alice 发送“Pay Bob $100”,你不希望有人重新发送 100 次)。

CSRF 令牌修补了用户操作身份验证中特定于 HTML 的弱点,其中第 3 方网站可以提交带有用户查看网站凭据的表单(例如 evil.example.com 上的 JavaScript 使用您的浏览器向 facebook.com 提交表单,以您身份进行身份验证)。

CSRF 令牌需要保密,否则攻击者将拥有伪造请求所需的缺失部分。

如果使用请求者的秘密签名,则 nonce 不必是秘密的(只要攻击者不能用另一个 nonce 替换一个 nonce)。

您可以允许使用 CSRF 令牌重播请求,并且仍然受到 CSRF 的保护(您对这是否是用户的故意行为感兴趣,但不一定希望阻止用户多次执行)。

事实上,这通常是非常有用的属性,例如允许用户使用返回按钮并重新提交具有更正值的表单。如果你用类似 Nonce 的机制来实现 CSRF 保护,当用户刷新提交的页面时,你会得到错误的警报。

在没有 Nonce 的情况下防止 CSRF 的一种简单方法是将会话 ID 放在隐藏字段中(不是存储会话中的值,而是会话本身的 ID,与您存储在 cookie 中 [session_id()在 PHP 中] 相同)。提交表单时,检查表单的会话 ID 是否与 cookie 中的 ID 匹配。这对 CSRF 来说就足够了,因为攻击者无法知道cookie 的(CSRF 只允许攻击者盲目发送 cookie)。

于 2012-03-21T11:14:38.720 回答
16

Nonce 通常是一些随机字符串,添加到请求中只是为了以不可预测的方式更改数据,用于计算签名。因此,nonce 通常不被任何服务器端业务逻辑使用。

而 CSRF-token 存储在服务器上的某个位置,传递给客户端并需要返回给服务器进行比较。如果匹配 - 然后确定。

因此,在您的情况下,最好将 csrf 令牌保存在会话变量中,例如

$_SESSION['csrf_token'] = bin2hex(random_bytes(16));

并在会话期间以您在应用程序中拥有的所有形式不变地使用它。

(如果没有random_bytes(),请使用random_compat 填充它。)

于 2011-04-17T04:39:30.927 回答
8

这有点像。“nonce”本身就是一次性密码。它可以作为加密盐,但基本上只是一个随机值。见WP:Nonce

但总而言之,一个随机数通常用作CSRF令牌。这是一个实现细节。与其他用例的不同之处在于它稍后会被断言。

于 2011-04-17T04:51:53.057 回答
0

CSRF 有一些限制。如果您有需要在新选项卡中打开任何页面或链接的要求,那么 CSRF 将不允许。现有令牌将只允许在新标签页中打开页面 5 次。当您尝试第 6 次打开时,它将创建与“服务器端 = 客户端令牌”不匹配的新令牌。较早的令牌将过期并创建新令牌(NONCE),在这种情况下,您将收到 404 或 405 错误。

于 2019-06-28T09:13:42.047 回答