什么是在PHP中保护会话变量的有效方法?

时间:2010-01-27 03:43:43

标签: php security session

我的网络应用程序几乎在整个应用程序中使用UserId ..

  • 在php中保护会话变量的最有效方法是什么?

  • 会话容易受到攻击吗?

  • 我应该在会话中保留UserId的加密值吗?

任何建议......

1 个答案:

答案 0 :(得分:17)

注意:取自my previous answer

术语

  • 用户:访客。
  • 客户端:安装在特定计算机上的特定网络软件。

了解会话

为了了解如何确保会话安全,您必须首先了解会话的工作方式。

让我们看看这段代码:

session_start();

一旦你调用它,PHP就会寻找一个名为PHPSESSID的cookie(默认情况下)。如果找不到,它将创建一个:

PHPSESSID=h8p6eoh3djplmnum2f696e4vq3

如果找到,则取PHPSESSID的值,然后加载相应的会话。该值称为session_id

这是客户唯一知道的事情。无论您添加到会话变量中的是什么,都会保留在服务器上,并且永远不会转移到客户端。如果更改$_SESSION的内容,则该变量不会更改。它会一直保持不变,直到你摧毁它或它超时。因此,尝试通过对其进行散列或通过其他方式对$_SESSION的内容进行模糊处理是没有用的,因为客户端从未接收或发送该信息。

然后,在新会话的情况下,您将设置变量:

$_SESSION['user'] = 'someuser';

客户永远不会看到这些信息。


问题

恶意用户窃取其他用户的session_id时可能会出现安全问题。如果没有某种检查,他就可以自由地冒充该用户。我们需要找到一种方法来唯一地识别客户端(而不是用户)。

一种策略(最有效)涉及检查启动会话的客户端的IP是否与使用会话的人员的IP相同。

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}

// The Check on subsequent load
if($_SESSION['ip'] != $_SERVER['REMOTE_ADDR']) {
    die('Session MAY have been hijacked');
}

该策略的问题在于,如果客户端使用负载均衡器,或者(在长时间会话中)用户具有动态IP,则会触发虚假警报。

另一个策略涉及检查客户端的用户代理:

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['agent'] = $_SERVER['HTTP_USER_AGENT'];
}

// The Check on subsequent load
if($_SESSION['agent'] != $_SERVER['HTTP_USER_AGENT']) {
    die('Session MAY have been hijacked');
}

该策略的缺点是,如果客户端升级其浏览器或安装插件(一些添加到用户代理),则用户代理字符串将更改,并将触发虚假警报。

另一种策略是在每5个请求上轮换session_id。这样,session_id理论上不会长时间被劫持。

if(logging_in()) {
    $_SESSION['user'] = 'someuser';
    $_SESSION['count'] = 5;
}

// The Check on subsequent load
if(($_SESSION['count'] -= 1) == 0) {
    session_regenerate_id();
    $_SESSION['count'] = 5;
}

您可以根据需要组合这些策略中的每一种,但您也会将缺点结合起来。

不幸的是,没有任何解决方案是万无一失的。如果您的session_id遭到入侵,那么您已经完成了很多工作。上述策略只是权宜之计。