【问题标题】:PHP Session security checksPHP 会话安全检查
【发布时间】:2015-01-07 09:51:09
【问题描述】:

所以我一直在阅读课程,我不得不说,我很困惑。 似乎会话在安全方面已经“损坏”了,为什么他们没有在会话代码本身中实施更多的安全检查......

无论如何,我的问题。我发现这个网站有很多会话安全检查:https://wblinks.com/notes/secure-session-management-tips/ 阅读其中大​​部分对我来说很有意义。然而,最让我困惑的是何时调用这些检查。

我会在每个页面上调用这些检查吗?一方面,这是有道理的,因为有人可以劫持或其他事情,每个页面上的会话,对吗?另一方面,在每个页面上完成这些检查会花费一些额外的时间,总体上可能会增加加载时间?


此时我得到了以下代码。

<?php

if ($_SESSION['_USER_LOOSE_IP'] != long2ip(ip2long($_SERVER['REMOTE_ADDR']) & ip2long("255.255.0.0"))
    || $_SESSION['_USER_AGENT'] != $_SERVER['HTTP_USER_AGENT']
    || $_SESSION['_USER_ACCEPT'] != $_SERVER['HTTP_ACCEPT']
    || $_SESSION['_USER_ACCEPT_ENCODING'] != $_SERVER['HTTP_ACCEPT_ENCODING']
    || $_SESSION['_USER_ACCEPT_LANG'] != $_SERVER['HTTP_ACCEPT_LANGUAGE']
    || $_SESSION['_USER_ACCEPT_CHARSET'] != $_SERVER['HTTP_ACCEPT_CHARSET']
    || !isset($_SESSION['MY_SERVER_GENERATED_THIS_SESSION'])) {


    // Destroy and start a new session
    sec_session_destroy(); // Destroy session on disk
    sec_session_start();

    // Log for attention of admin and re-authenticate user...
}

if ($_SESSION['SESSION_START_TIME'] < (strtotime("-1 hour")) || $_SESSION['_USER_LAST_ACTIVITY'] < (strtotime("-20 mins"))) {
    sec_session_destroy();
    //Expire session and re-authenticate user...
}

function sec_session_start() {
    setcookie("sid",            // Name
          session_id(),         // Value
          strtotime("+1 hour"), // Expiry
          "/",                  // Path
          ".serellyn.net",      // Domain
          true,                 // HTTPS Only
          true);                // HTTP Only

    // Store these values into the session so I can check on subsequent requests.
    $_SESSION['_USER_AGENT']           = $_SERVER['HTTP_USER_AGENT'];
    $_SESSION['_USER_ACCEPT']          = $_SERVER['HTTP_ACCEPT'];
    $_SESSION['_USER_ACCEPT_ENCODING'] = $_SERVER['HTTP_ACCEPT_ENCODING'];
    $_SESSION['_USER_ACCEPT_LANG']     = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
    $_SESSION['_USER_ACCEPT_CHARSET']  = $_SERVER['HTTP_ACCEPT_CHARSET'];
    $_SESSION['MY_SERVER_GENERATED_THIS_SESSION'] = true;

    // Only use the first two blocks of the IP (loose IP check). Use a
    // netmask of 255.255.0.0 to get the first two blocks only.
    $_SESSION['_USER_LOOSE_IP'] = long2ip(ip2long($_SERVER['REMOTE_ADDR']) 
                                          & ip2long("255.255.0.0"));

    $_SESSION['SESSION_START_TIME'] = time();
    $_SESSION['_USER_LAST_ACTIVITY'] = time();

    sec_session_start();            // Start the PHP session 
}

function sec_session_destroy() {
    session_unset(); 
    session_destroy();
    session_start();
    session_regenerate_id(true);
}

我的最后一个问题是,上面的代码是否有意义,或者您有什么建议可以使它更好或更容易混淆。我应该在每一页上都包含这个,还是只在几页上?

提前致谢

【问题讨论】:

  • " 看来会话在安全方面已经被“破坏”了”,嗯?这就像在说“看起来汽车就像安全一样‘危险’”
  • 另请注意,在正确设置会话并且仅使用加密连接时,上述大部分内容已得到处理。
  • 还要注意ipv6地址的ip检查会失败。

标签: php security session


【解决方案1】:

为什么他们没有在会话代码本身中实施更多的安全检查...

通常的“会话”模型是会话 ID 是一个强机密,泄露该 ID 的任何内容都将被视为漏洞。

此处列出的其他标头不是机密,并且在许多会导致会话 ID 泄漏的相同情况下很可能是可证伪的。因此,检查它们的好处不太明显;这样做只是对会话劫持漏洞的部分缓解。另一方面,存在明显的兼容性缺陷:

$_SESSION['_USER_AGENT'] != $_SERVER['HTTP_USER_AGENT']

如果浏览器升级发生在会话内,或者在某些情况下,用户安装或升级浏览器插件/扩展时无需重新启动,用户代理可能会发生变化。

$_SESSION['_USER_ACCEPT'] != $_SERVER['HTTP_ACCEPT']

accept 标头会根据它所期望的资源类型而变化,因此如果您执行诸如从 PHP 提供图像之类的操作,则会中断。

($_SESSION['_USER_LOOSE_IP'] != long2ip(ip2long($_SERVER['REMOTE_ADDR']) & ip2long("255.255.0.0"))

这比精确的 IP 匹配要好,但对于从一个电信或 wifi 网络切换到另一个的移动用户来说仍然会中断。

您当然可以将这些标头中的更改用作启发式方法,例如决定是否需要对特定敏感操作或一般风险评级交易进行重新身份验证。但是当它们中的任何一个发生变化时立即中断会话会使某些用户使用您的网站的体验变得更糟。

这是一种权衡,每个应用程序可能需要不同的方法,并且可能需要将其与应用程序使用的特定知识联系起来。因此,大多数会话的实现都不会,而且默认情况下也不能真正做到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    相关资源
    最近更新 更多