PHP Session 安全检查
PHP Session security checks
所以我一直在阅读 sessions,我不得不说,我很困惑。
似乎 sessions 和 'broken' 一样安全,为什么他们没有在 sessions 代码本身中实施更多安全检查...
无论如何,我的问题。我发现这个网站有很多 session 安全检查:https://wblinks.com/notes/secure-session-management-tips/ 通读其中的大部分内容对我来说很有意义。然而,最让我困惑的是什么时候也调用这些检查。
我是否在每个 页面上调用这些检查?一方面,这是有道理的,因为有人可以在每个页面上劫持或其他东西 session 对吧?另一方面,在每个页面上完成这些检查会花费一些额外的时间,总的来说可能会增加加载时间?
此时我得到了以下代码。
<?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);
}
我的最后一个问题是,上面的代码是否有意义,或者您有什么建议可以让它变得更好或更少混淆。我应该在每一页上都包括这个,还是只在几页上?
提前致谢
Why haven't they implemented more security checks in the sessions code itself...
通常的“session”模型是 session ID 是一个强大的秘密,任何泄露该 ID 的行为都将被视为漏洞。
此处列出的其他 header 不是秘密,并且在许多可能导致 session ID 泄露的相同情况下很可能是可伪造的。所以检查它们的好处不太明显;这样做只是对 session 劫持漏洞的部分缓解。另一方面,存在显着的兼容性缺陷:
$_SESSION['_USER_AGENT'] != $_SERVER['HTTP_USER_AGENT']
如果浏览器升级发生在 session 内,或者在某些情况下,用户安装或升级浏览器 plugin/extension。
,则用户代理可以更改
$_SESSION['_USER_ACCEPT'] != $_SERVER['HTTP_ACCEPT']
accept header 将根据它期望的资源类型而改变,因此如果您执行类似从 PHP 提供图像的操作,这将中断。
($_SESSION['_USER_LOOSE_IP'] != long2ip(ip2long($_SERVER['REMOTE_ADDR']) & ip2long("255.255.0.0"))
这比精确的 IP 匹配要好,但对于从一个电信公司或 wifi 网络切换到另一个的移动用户来说仍然会中断。
您当然可以将这些 header 中的更改用作启发式方法,例如决定是否需要对特定敏感操作或一般 risk-rating 事务进行重新身份验证。但是,当它们中的任何一个发生变化时立即破坏 session 会使某些用户使用您的网站的体验变得更糟。
这是一个 trade-off,每个应用程序可能需要不同的方法,并且可能需要将其与应用程序用法的特定知识联系起来。因此,大多数 sessions 的实现默认情况下不会,也不能真正做到这一点。
所以我一直在阅读 sessions,我不得不说,我很困惑。 似乎 sessions 和 'broken' 一样安全,为什么他们没有在 sessions 代码本身中实施更多安全检查...
无论如何,我的问题。我发现这个网站有很多 session 安全检查:https://wblinks.com/notes/secure-session-management-tips/ 通读其中的大部分内容对我来说很有意义。然而,最让我困惑的是什么时候也调用这些检查。
我是否在每个 页面上调用这些检查?一方面,这是有道理的,因为有人可以在每个页面上劫持或其他东西 session 对吧?另一方面,在每个页面上完成这些检查会花费一些额外的时间,总的来说可能会增加加载时间?
此时我得到了以下代码。
<?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);
}
我的最后一个问题是,上面的代码是否有意义,或者您有什么建议可以让它变得更好或更少混淆。我应该在每一页上都包括这个,还是只在几页上?
提前致谢
Why haven't they implemented more security checks in the sessions code itself...
通常的“session”模型是 session ID 是一个强大的秘密,任何泄露该 ID 的行为都将被视为漏洞。
此处列出的其他 header 不是秘密,并且在许多可能导致 session ID 泄露的相同情况下很可能是可伪造的。所以检查它们的好处不太明显;这样做只是对 session 劫持漏洞的部分缓解。另一方面,存在显着的兼容性缺陷:
$_SESSION['_USER_AGENT'] != $_SERVER['HTTP_USER_AGENT']
如果浏览器升级发生在 session 内,或者在某些情况下,用户安装或升级浏览器 plugin/extension。
,则用户代理可以更改$_SESSION['_USER_ACCEPT'] != $_SERVER['HTTP_ACCEPT']
accept header 将根据它期望的资源类型而改变,因此如果您执行类似从 PHP 提供图像的操作,这将中断。
($_SESSION['_USER_LOOSE_IP'] != long2ip(ip2long($_SERVER['REMOTE_ADDR']) & ip2long("255.255.0.0"))
这比精确的 IP 匹配要好,但对于从一个电信公司或 wifi 网络切换到另一个的移动用户来说仍然会中断。
您当然可以将这些 header 中的更改用作启发式方法,例如决定是否需要对特定敏感操作或一般 risk-rating 事务进行重新身份验证。但是,当它们中的任何一个发生变化时立即破坏 session 会使某些用户使用您的网站的体验变得更糟。
这是一个 trade-off,每个应用程序可能需要不同的方法,并且可能需要将其与应用程序用法的特定知识联系起来。因此,大多数 sessions 的实现默认情况下不会,也不能真正做到这一点。