dqmhgz5848 2016-04-21 09:38
浏览 66
已采纳

PHP会话安全 - 金丝雀会话

I am learning PHP after using Classic ASP since 2001.

I've come to the point of working out how to secure the admin section of a site I'm working on, and have been reading here:

https://paragonie.com/blog/2015/04/fast-track-safe-and-secure-php-sessions

I've seen that it appears to be bad practice to bind a session to an IP address - e.g.

Check if the $_SERVER['REMOTE_ADDR'] matches $_SESSION['ip']

As taken from the link above:

Some systems like to bind a session to a particular IP address. This is not generally recommended; Tor users, in particular, will have difficulty staying authenticated. You can enforce this restriction here too.

session_start();

// Make sure we have a canary set
if (!isset($_SESSION['canary'])) {
    session_regenerate_id(true);
    $_SESSION['canary'] = [
        'birth' => time(),
        'IP' => $_SERVER['REMOTE_ADDR']
    ];
}
if ($_SESSION['canary']['IP'] !== $_SERVER['REMOTE_ADDR'])) {
    session_regenerate_id(true);
    // Delete everything:
    foreach (array_keys($_SESSION) as $key) {
        unset($_SESSION[$key]);
    }
    $_SESSION['canary'] = [
        'birth' => time(),
        'IP' => $_SERVER['REMOTE_ADDR']
    ];
}
// Regenerate session ID every five minutes:
if ($_SESSION['canary']['birth'] < time() - 300) {
    session_regenerate_id(true);
    $_SESSION['canary']['birth'] = time();
}

I can't work this one out - is the blog post saying that it is wrong to bind a session to an IP address, and then posting code showing how you can do that?

Or is the "canary" session code they use not actually binding a session to an IP address?

Assuming the code isn't binding a session to an IP address and that it would be good practice to use it, then I'm a bit confused about how I would use this canary session - would I put this bit on my login page, once a user has successfully logged in:

// Make sure we have a canary set
if (!isset($_SESSION['canary'])) {
    session_regenerate_id(true);
    $_SESSION['canary'] = [
        'birth' => time(),
        'IP' => $_SERVER['REMOTE_ADDR']
    ];
}

// set my own session variable as well
if (!isset($_SESSION['name'])) {
    $_SESSION['name'] = $name; // $name = value from database
    header('Location:admin-home.php');
    exit;
}

And then put these bits at the top of any pages which are user protected:

session_start();

// ####################################################################################################
// Is User Logged In?
// ####################################################################################################

$name = $_SESSION['name'];

if (!isset($name)) {
    header('Location:login.php');
    exit;    
}

// ####################################################################################################
// Canary Session?
// https://paragonie.com/blog/2015/04/fast-track-safe-and-secure-php-sessions
// ####################################################################################################

if ($_SESSION['canary']['IP'] !== $_SERVER['REMOTE_ADDR']) {
    session_regenerate_id(true);
    // Delete everything:
    foreach (array_keys($_SESSION) as $key) {
        unset($_SESSION[$key]);
    }
    $_SESSION['canary'] = [
        'birth' => time(),
        'IP' => $_SERVER['REMOTE_ADDR']
    ];
}

// Regenerate session ID every five minutes:
if ($_SESSION['canary']['birth'] < time() - 300) {
    session_regenerate_id(true);
    $_SESSION['canary']['birth'] = time();
}

I will also be using HTTPS for the login and admin pages.

  • 写回答

1条回答 默认 最新

  • duanjiao6730 2016-04-22 15:00
    关注

    The way PHP handles sessions, is to generate a unique session id for each user, and store it in a cookie (default name PHPSESSID). This works well across IP changes, and gives different session on different browsers on the same machine.

    To give more security, you can also save user ip and user agent in session, and check that on every request. I'm not sure whether PHP does this by default or not, but it would be rather simple to implement it.

    You can also look for session implementation on famous frameworks (Laravel, Symfony, ...) to see how they do it. I leave it to you to further investigate topic, as it should be a bit of googling and reading source code.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!