Php 是否可以组合CSRF和Nonce令牌?

Php 是否可以组合CSRF和Nonce令牌?,php,csrf,nonce,Php,Csrf,Nonce,首先是一些上下文。 我一直在使用nonce令牌对表单数据进行签名,其方式与wordpress允许将操作附加到nonce的方式相同: // editing post id:10 $post_id = 10; $nonce = create_nonce( 'edit-post-'.$post_id ); echo '<input type="hidden" name="post_id" value="'.$post_id.'">'; echo '<input type="hidde

首先是一些上下文。
我一直在使用nonce令牌对表单数据进行签名,其方式与
wordpress
允许将操作附加到nonce的方式相同:

// editing post id:10
$post_id = 10;
$nonce = create_nonce( 'edit-post-'.$post_id );
echo '<input type="hidden" name="post_id" value="'.$post_id.'">';
echo '<input type="hidden" name="nonce" value="'.$nonce.'">';
到目前为止,我将此方法误解为一种反CSRF令牌,它为我提供了CSRF保护。
当我深入研究CSRF问题时,我发现该解决方案不能100%保护我免受CSRF的影响,因为:

  • 可以使用接收到的数据在服务器中重建nonce。不得重建CSRF
  • 在一个窗口时间内,窗体的nonce标记将相同。每次请求时,CSRF必须是唯一的
  • 所以,我的问题是:


    可以在一个表单中使用两个令牌来保护CSRF和数据签名吗?有没有办法将这两个令牌组合起来?

    通常,nonce需要保存在服务器端的某个位置。如果在验证时重新生成nonce,则表示nonce是基于输入的可预测值。这是非常无用的,因为这是一个静态值。这不是暂时的

    nonce的工作方式是:

  • 构建表单
  • 生成一个随机值,即nonce
  • 在会话中保存nonce,并将其放入表单中的隐藏字段中
  • 提交表单后,检查提交的nonce是否与会话中的nonce对应
  • 其他任何东西都只是action+post-id的校验和,这是非常无用的

    通过获取所有预期字段和其他预期静态值的名称,并将它们的哈希值添加到会话中,您可以使用待提交字段的校验和轻松地扩展这个适当的nonce过程。例如:

    sha1(join(',', array('first_name', 'last_name', $nonce)))
    

    提交表单后,获取所有收到的字段名,再次生成相同的哈希,并检查它是否与会话中的相同。如果没有,则有人篡改了表单。

    PS:我对Wordpress了解不够,无法告诉您
    create\u nonce
    函数应该做什么。我的Wordpress nonces的一个问题是它们是静态的(对于相同的输入,它们每小时都会变化),因此我怀疑是否有足够的CSRF证据。我看到,为了得到适当的保护,我需要一些绝对不可复制的值。但是我仍然需要防止有人更改资源的
    id
    (例如)并将更改提交到新的
    id
    (即使新的
    id
    是它的属性)。对于将数据提交到其他id的问题,您需要权限检查和数据验证。也就是说,如果用户被允许编辑具有特定id的条目,并且数据对其有效,那么他是否正确地使用了正确的表单或“一起黑客攻击”实际上并不重要。但是,正如我在回答中所描述的,即使使用CSRF保护也可以通过向表单和会话添加所有静态数据的散列来捕获。本例中的静态数据都是表单元素名和隐藏/只读数据,包括条目id。但该散列将是不同的标记吗?或者与您描述的相同的
    nonce
    ?您只需在表单中提交包含nonce的最终哈希。不过,您必须将nonce存储在服务器上,以便再次从提交的表单数据+nonce计算相同的哈希值。
    sha1(join(',', array('first_name', 'last_name', $nonce)))