PHP会话安全

时间:2008-08-02 02:41:34

标签: security php

使用PHP维护负责任的会话安全性有哪些指导原则?整个网络都有信息,这是关于它在一个地方落地的时间!

13 个答案:

答案 0 :(得分:88)

为了确保会话安全,有几件事要做:

  1. 在对用户进行身份验证或执行敏感操作时使用SSL。
  2. 每当安全级别更改(例如登录)时,重新生成会话ID。如果愿意,您甚至可以在每个请求中重新生成会话ID。
  3. 让会话超时
  4. 不要使用注册全局
  5. 在服务器上存储身份验证详细信息。也就是说,不要在cookie中发送用户名等详细信息。
  6. 检查$_SERVER['HTTP_USER_AGENT']。这为会话劫持增加了一个小障碍。您还可以检查IP地址。但是这会导致由于多个Internet连接上的负载平衡而导致IP地址发生变化的用户出现问题(在我们的环境中就是这种情况)。
  7. 锁定对文件系统上会话的访问权限或使用自定义会话处理
  8. 对于敏感操作,请考虑要求登录用户再次提供其身份验证详细信息

答案 1 :(得分:15)

一个准则是每次会话的安全级别更改时调用session_regenerate_id。这有助于防止会话劫持。

答案 2 :(得分:11)

我认为其中一个主要问题(在PHP 6中正在解决)是register_globals。现在,用于避免register_globals的标准方法之一是使用$_REQUEST$_GET$_POST数组。

这种“正确”的方式(从5.2开始,尽管那里有一个小小的错误,但从6开始稳定,即将到来)是通过filters

所以而不是:

$username = $_POST["username"];

你会这样做:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);

甚至只是:

$username = filter_input(INPUT_POST, 'username');

答案 3 :(得分:11)

我的两个(或更多)美分:

  • 不相信任何人
  • 过滤输入,转义输出(cookie,会话数据也是您的输入)
  • 避免使用XSS(保持HTML格式正确,请查看PHPTALHTMLPurifier
  • Defense in depth
  • 不要公开数据

关于这个主题,有一本很小但很好的书:Essential PHP Security by Chris Shiflett

Essential PHP Security http://shiflett.org/images/essential-php-security-small.png

在本书的主页上,您将找到一些有趣的代码示例和示例章节。

您可以使用上述技术(IP& UserAgent),如下所述:How to avoid identity theft

答案 4 :(得分:9)

This session fixation paper有很好的指针可能会发生攻击。另请参阅session fixation page at Wikipedia

答案 5 :(得分:5)

根据我的经验,使用IP地址并不是最好的主意。例如;我的办公室有两个IP地址,根据负载使用,我们经常使用IP地址遇到问题。

相反,我选择将会话存储在我服务器上的域的单独数据库中。这样,文件系统上没有人可以访问该会话信息。这对于3.0之前的phpBB非常有帮助(他们已经解决了这个问题),但我认为这仍然是一个好主意。

答案 6 :(得分:3)

的php.ini

session.cookie_httponly = 1
change session name from default PHPSESSID

eq Apache添加标题:

X-XSS-Protection    1

答案 7 :(得分:3)

这非常简单明了,但每次使用后一定要session_destroy。如果用户没有明确注销,这可能很难实现,因此可以设置计时器来执行此操作。

这是关于setTimer()和clearTimer()的好tutorial

答案 8 :(得分:3)

PHP会话和安全性(除会话劫持之外)的主要问题在于您所处的环境。默认情况下,PHP将会话数据存储在OS的临时目录中的文件中。没有任何特殊的想法或计划,这是一个世界可读的目录,因此所有会话信息对任何有权访问服务器的人都是公开的。

至于维护多个服务器上的会话。此时,将PHP切换到用户处理的会话会更好,在这些会话中,它会将您提供的函数调用到CRUD(创建,读取,更新,删除)会话数据。此时,您可以将会话信息存储在数据库或memcache之类的解决方案中,以便所有应用程序服务器都可以访问数据。

如果您在共享服务器上,存储您自己的会话也可能是有利的,因为它可以让您将它存储在数据库中,而您通常可以对文件系统进行更多控制。

答案 9 :(得分:3)

我像这样设置会话 -

登录页面上的

$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);

(在配置页面上定义的短语)

然后在整个网站其余部分的标题上:

session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {       
    session_destroy();
    header('Location: http://website login page/');
    exit();     
}

答案 10 :(得分:2)

我会检查IP和用户代理以查看它们是否更改

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
    //Something fishy is going on here?
}

答案 11 :(得分:2)

您需要确保会话数据是安全的。通过查看php.ini或使用phpinfo(),您可以找到会话设置。 _session.save_path_告诉你它们的保存位置。

检查文件夹及其父项的权限。它不应该是公共的(/ tmp),也不能被共享服务器上的其他网站访问。

假设您仍然想使用php会话,您可以通过更改_session.save_path_来设置php以使用其他文件夹,或者通过更改_session.save_handler_来保存数据库中的数据。

您可以在您的站点根文件夹中的.htaccess文件中设置php.ini(某些提供程序允许)或apache + mod_php中的_session.save_path_: php_value session.save_path "/home/example.com/html/session"。您也可以使用_session_save_path()_。

在运行时设置它

检查Chris Shiflett's tutorialZend_Session_SaveHandler_DbTable以设置和替代会话处理程序。

答案 12 :(得分:2)

如果您使用session_set_save_handler(),则可以设置自己的会话处理程序。例如,您可以将会话存储在数据库中。有关数据库会话处理程序的示例,请参阅php.net注释。

如果您有多个服务器,数据库会话也很好,否则如果您使用基于文件的会话,则需要确保每个Web服务器都可以访问相同的文件系统来读/写会话。