PHP 会话再生安全

Col*_*law 3 php security session

我在用 PHP 做一些非常基本的会话安全类型的事情时遇到了困难:

  • 从非认证上下文切换到认证上下文时,应生成新的会话 ID
  • 从经过身份验证的上下文切换到未经身份验证的上下文时,应生成新的会话 ID

我想要做的不仅是在切换上下文时重新生成会话 ID,而且在切换这些上下文时立即将某些内容(例如 FLASH)放入会话中。这三页应该有希望澄清我的期望:

<?php
/* page1.php */
session_start();
# Just putting something in the session which I expect to
# not show up later
$_SESSION['INFO1'] = 'INFO1';
?>
<html>
<a href="page2.php">Page 2</a>
<?php print_r($_SESSION) ?>
</html>
Run Code Online (Sandbox Code Playgroud)

因此,当显示此页面时,我希望看到INFO1显示。我也希望当我回到这里时不要看到INFO2出现。如果我还没有会话 ID,我希望得到一个(我有)。

<?php
# page2.php
session_destroy();
session_regenerate_id(TRUE);
$_SESSION['INFO2'] = 'From page 2';
session_write_close();
header('Location: page3.php');
exit;
?>
Run Code Online (Sandbox Code Playgroud)

这最类似于注销功能 - 我们通过传递TRUEsession_regenerate_id. 另外,我在(大概)会话中放了一些东西——它可能像一个闪存——说“你已经成功注销了。

#page3.php
<html>
<body>
<?php session_start(); ?>
<?php print_r($_SESSION); ?>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

在此页面上,我预计会发生两件事:

  • 重定向来自page2.php应该向我发送了一个新的会话 ID cookie(它没有)
  • 我希望print_r从 打印信息INFO2,而不是INFO1. 它没有来自 的信息INFO1,但不包括来自 的信息INFO2

我有非常非常不一致的结果session_regenerate_id和重定向。手动发送该Set-Cookie标头似乎很麻烦- 但即使我没有,也session_regenerate_id(TRUE)应该使旧的会话 ID 无效 - 所以即使浏览器由于某种原因没有获得新的会话 ID,它也不会看到会话中的任何信息,因为旧会话已失效。

有没有其他人有过这类问题的经验?有没有解决这些问题的好方法?

Eev*_*vee 5

基于对文档session_regenerate_id,它听起来就像是会议的内容会始终保留。您正在向它传递一个TRUE参数,但这只会删除磁盘上的实际会话文件;存储在其中的值被保留$_SESSION,然后写入新会话。

所以也许手动清除它:

$_SESSION = array();
Run Code Online (Sandbox Code Playgroud)

不过,不知道为什么你没有看到新的 cookie。你在哪里检查,你看到了什么?

编辑:正如 OP 在下面的评论中所揭示的那样,问题似乎是 page2 从未调用session_start过加载第一个会话。产生以下结果:

<?php
    session_start();    # Load the old session
    session_destroy();  # Nuke it
    session_unset();    # Delete its contents
    session_start();    # Create a new session
    session_regenerate_id(TRUE);  # Ensure it has a new id
    $_SESSION['FLASH'] = "You've been logged out";
    session_write_close();  # Convince it to write
    header('Location: index.php');
?>
Run Code Online (Sandbox Code Playgroud)

我不知道这是否是最小的。弄清楚可以删除多少内容留给读者作为练习。