2016-04-21 141 views
2

我学习PHP中使用传统的ASP自2001年以来PHP会话安全 - 金丝雀会议

我是来工作如何确保我的工作网站的管理部分后点,和一直在阅读这里:

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

我已经看到了似乎是绑定一个会话的IP地址是不好的做法 - 例如,

检查是否匹配$_SERVER['REMOTE_ADDR']$_SESSION['ip']

由于从链接采取以上:

一些系统喜欢会话绑定到特定的IP地址。这通常不被推荐;特别是Tor用户将难以保持认证。您也可以在这里强制执行此限制。

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(); 
} 

我不能工作这一个 - 的博客文章说,这是错误的会话绑定到一个IP地址,然后张贴代码展示了如何做到这一点?

或者他们使用的“canary”会话代码实际上并没有将会话绑定到IP地址?

假设代码没有将会话绑定到IP地址,并且使用它会是一个很好的做法,那么我对如何使用这个金丝雀会话感到困惑 - 我会把这一点我的登录页面,一旦用户成功登录:

// 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; 
} 

然后把这些位在任何页面的顶部这是用户的保护:

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(); 
} 

我也将使用HTTPS的登录和管理页面。

+2

将会话绑定到IP没有任何作用,因为在同一个IP后面可能有多个人,或者使用您的站点的人可能在每个请求上拥有不同的IP(连接中断,他们重新连接到他们的ISP并接收新的IP)。我建议将会话处理包装在一个类中,这样它更具可读性和可维护性。不要绑定到IP。您可以使用PHP的内置会话机制,但也有其他选择(老实说,PHP的内置机制并不是最好的),您可以探索流行的PHP框架,甚至使用他们的会话处理代码。 – Mjh

+0

感谢@Mjh的建议。我不是一个合适的程序员或编码员。我试图运用有限的智能理解类和框架,并迅速意识到自己的局限性,因此走下了程序化的路线。 – 4532066

+0

*使用您的网站的人可以在每个请求上拥有不同的IP * ... AOL是臭名昭着的 - 特别是如果您尝试在子域之间维护会话。 @Mjh – CD001

回答

0

PHP处理会话的方式是为每个用户生成一个唯一的会话ID,并将其存储在cookie(默认名称PHPSESSID)中。这适用于IP更改,并在同一台计算机上的不同浏览器上提供不同的会话。

为了提供更高的安全性,您还可以在会话中保存用户ip和用户代理,并检查每个请求。我不确定PHP是否默认这样做,但实现它会相当简单。

您还可以在着名框架(Laravel,Symfony,...)上查看会话实现,了解它们是如何实现的。我把它留给你进一步调查主题,因为它应该是一个谷歌搜索和阅读源代码。