PHP在表单提交中复制订单,即使使用CSRF令牌

PHP在表单提交中复制订单,即使使用CSRF令牌,php,duplicates,token,csrf,lighttpd,Php,Duplicates,Token,Csrf,Lighttpd,对于用PHP编写的应用程序中的“确认订单”页面,我需要防止多次提交表单,这样我们就不会收到重复的订单。我尝试用两种方法来处理这个问题: 对于支持javascript的用户,在上禁用提交按钮 点击 使用表单生成令牌并存储在会话中。在第一次提交时,将对它们进行比较,并删除会话令牌。因此,应拒绝没有匹配令牌的后续提交。这应有防止CSRF攻击的额外好处 我知道这两种做法都相当标准,但问题似乎仍然存在?在禁用js的情况下,如果我多次单击submit按钮,我将获得X个重复订单 这让我觉得这个问题可能与配置有

对于用PHP编写的应用程序中的“确认订单”页面,我需要防止多次提交表单,这样我们就不会收到重复的订单。我尝试用两种方法来处理这个问题:

  • 对于支持javascript的用户,在上禁用提交按钮 点击
  • 使用表单生成令牌并存储在会话中。在第一次提交时,将对它们进行比较,并删除会话令牌。因此,应拒绝没有匹配令牌的后续提交。这应有防止CSRF攻击的额外好处
  • 我知道这两种做法都相当标准,但问题似乎仍然存在?在禁用js的情况下,如果我多次单击submit按钮,我将获得X个重复订单

    这让我觉得这个问题可能与配置有关。它托管在lighthttpd上,php使用cgi fcgi编译。我我不完全确定这是否相关,但我不知道这是怎么可能的

    服务器代码如下(为简洁起见,请删节):

    
    
    根据Ghigo的评论,我对代码进行了重构,使其能够正常工作


    这个问题最终是来自iframe和表单提交的会话锁定问题。确保尽早关闭会话是解决此问题的关键。

    使会话尽可能短地打开,并使用
    会话写入关闭()强制保存会话。
    。使用
    $\u SESSION
    输出html是一种不好的做法。在本地var上复制所需的会话数据,然后发布会话。谢谢。该应用程序是一个遗留应用程序,我正在修复一个bug。我通常不会在HTML输出中引用$\会话。缺少会议记录确实是问题的一部分。问题在于,原始表单提交是以iframe的形式进行的,iframe会锁定会话,因此不会取消设置。使用session\u write\u close确实可以解决这个问题,但会带来后续会话更改无法正确更新的进一步问题,即使随后使用session\u start。应重新构造代码,以便所有$\u会话访问都发生在session\u start()session\u write\u close()之间。我理解遗留代码必须工作,所以您可以考虑一个相当丑陋的黑客:在代码> SeStOraceWrreWixEclipse()/代码>之后,搜索所有$i会话访问,重新打开会话,修改会话数据并再次关闭它。当然表现很差,但它应该能起到作用。
    <?php
        $_SESSION['token'] = uniqid('', true);
    ?>
    <form name="myform" action="confirm" method="POST">
      <!--.... -->
     <input type="hidden" name="csrftoken" value="<?php echo $_SESSION['token']; ?>" />
     <input type="submit" name="submit" />
    
    <?php
       if ($_POST['csrftoken'] == $_SESSION['token']) {
           //proceed and process order
           unset($_SESSION['token']);
       }
    
    ?>