【问题标题】:Passing PHP Session ID as a POST parameter将 PHP 会话 ID 作为 POST 参数传递
【发布时间】:2021-11-07 16:42:02
【问题描述】:

鉴于我最近的问题 (PHP - Session lost/emptied on form post),会话 ID 在发布表单时几乎随机重新生成(登录 -> 将项目添加到购物篮或将项目添加到购物篮 -> 登录),从而导致会话数据丢失。一个变通方法被发现,我可以将会话 ID 作为隐藏输入传递,以强制会话 ID 自行维护。这是一个实用的解决方法吗?这会让我面临任何漏洞吗?

请注意,我的网站是在共享服务器上运行的。

【问题讨论】:

    标签: php forms security session


    【解决方案1】:

    我会在黑暗中试一试,猜测当您将表单提交到不同的子域时,即您在 http://www.example.com 上,并且您正在提交到 https://secure.example.com 等。

    如果是这样,您需要确保会话 cookie 域设置为使用您网站的所有子域,而不仅仅是您当前的子域。您可以通过以下方式进行检查:

    ini_get('session.cookie_domain');
    // if this outputs something like "www.example.com" and you're submitting to
    // "somethingelse.example.com", here's your problem.
    

    如果设置不正确,可以在 php.ini 或脚本中设置:

    ini_set('session.cookie_domain', '.example.com');  // or...
    session_set_cookie_params(ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), '.example.com');
    
    session_start();
    

    ... 或者,您可以确保在提交表单时使用相同的子域,因为在这种情况下很少有充分的理由使用不同的子域。

    或者您的问题可能完全不相关。无论如何都值得一试。

    但是,正如@Kaustubh Karkare 所说,通过表单传递会话变量的安全性与通过 cookie 传递它们的安全性相同。至于实用性,即使不经常使用,它也是一种非常合理的传递会话 ID 的方式。

    【讨论】:

    • 我没有设置这个,但我发布到同一个域,同一个文件(使用 GET 分页结构)。由于这是共享主机,这可能是原因吗?
    • 如果不查看您的页面,就无法真正判断问题所在,但如果您发布到 $_SERVER['PHP_SELF'] 那么这不太可能是问题......我只是知道当我处理这个问题(丢失会话)时,问题与子域相关。
    • 我应该只设置 ini_set('session.cookie_domain', '.example.com');作为预防措施?
    • 先运行一个测试。 if ($_SERVER['SCRIPT_URI'] != $_SERVER['HTTP_REFERER']) { echo 'potential problem [domain mismatch]: '.$_SERVER['SCRIPT_URI'].' != '.$_SERVER['HTTP_REFERER']; } if (!preg_match('/^\./', $scd = ini_get('session.cookie_domain')) && $scd != $_SERVER['HTTP_HOST']) { echo 'potential problem [cookie domain]: ['.$scd.'] & ['.$_SERVER['HTTP_HOST'].']'; } ... 如果 $scd 为空,它可能是也可能不是问题,但是按照您的建议设置它作为预防措施至少可以确保它按照您想要的方式设置。
    【解决方案2】:

    它不会影响您的安全级别。会话 ID 作为 cookie 存储在用户的浏览器中,您建议将其保存在 HTML 源中。无论哪种方式,最终用户或使用网络嗅探器的恶意实体都将能够访问这些数据。因此,如果它使您的工作更轻松,您可以使用它。

    【讨论】:

      【解决方案3】:

      不要发布它,而是从您的表单转到您的操作页面并使用它

      <?php
      
      //let's start the session
      session_start();
      
      $_SESSION['whateveryouwanttocallit'] = session_id()
      
      ?>
      

      所以基本上根本不发....

      您可以通过以下方式检查:

      <?php print_r($_SESSION)?>
      

      并且可以确认到:&lt;?php echo session_id()?&gt;

      但是,在回答您的问题时,这不是一个好的解决方法。

      通过将会话 ID 发布到您的会话,您只是创建了信息的副本并将其命名为您想要的任何名称,会话 ID 已经在您的会话中。

      此外,如果您打算在隐藏的输入中使用会话 ID 作为 cookie 的一种形式,以确保他们有关该用户的信息不会丢失,那么问题将是:

      1. 具有此新创建会话 ID 的会话也将被擦除。
      2. 即使保留,会话 ID 也会重新生成,因此是不同的字符串。

      【讨论】:

        猜你喜欢
        • 2012-06-02
        • 2015-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-28
        • 2013-09-14
        • 2023-03-15
        • 2012-03-15
        相关资源
        最近更新 更多