【问题标题】:PHP Session Lost, suhosin unchangeablePHP Session Lost, suhosin 不变
【发布时间】:2013-10-28 02:53:55
【问题描述】:

在 Ubuntu 12.04、Apache2、PHP5 服务器上,安装了 suhosin 扩展。 (phpinfo page)

这是一个通过自动更新提供最新安全更新的专用服务器。

我创建了以下测试脚本 (test script without setting suhosin conf)

session_start();

$error = 0;
ob_implicit_flush(true);

if ($_GET['is'] == 'set'){
    session_set_cookie_params ( '3600','/','.theparentingplace.com',false, false );
    error_log( "Old 'suhosin.session.encrypt': " . print_r( ini_set('suhosin.session.encrypt', 0), true) );    
    error_log( "Old 'suhosin.session.cryptdocroot': " . print_r( ini_set('suhosin.session.cryptdocroot', 0), true) );    
    error_log( "Old 'suhosin.cookie.cryptdocroot.': " . print_r( ini_set('suhosin.cookie.cryptdocroot', 0), true) );
}



if (empty($_SERVER['HTTPS']) && !$error){
    $_SESSION['test'] = 'abc';
    header('Location: https://'.$_SERVER['SERVER_NAME']
     .'/http_https_session_test.php');

}else{
    if ($_SESSION['test'] == 'abc'){
        print "Success." . $_SESSION['test'];
    }else{
        print "Fail.". print_r($_SESSION['test'],1);
    }
}

错误日志显示:

[Sat Oct 26 20:00:23 2013] [error] [client 103.29.31.35] Old 'suhosin.session.encrypt': 
[Sat Oct 26 20:00:23 2013] [error] [client 103.29.31.35] Old 'suhosin.session.cryptdocroot': 
[Sat Oct 26 20:00:23 2013] [error] [client 103.29.31.35] Old 'suhosin.cookie.cryptdocroot.'

其他 SO 帖子建议检查 session.cookie_secure 和 session.http_only 参数。两者都在此服务器上关闭。此外,我尝试实现关闭特定的 suhosin 设置,或者使用 suhosin.simulation=On 完全关闭 suhosin 我在 php.ini 中都尝试过这个

此脚本返回失败。如果脚本使用 is=set 参数运行,则设置参数失败(test script 2

在另一台专用服务器上,测试脚本工作正常,即。 https url 获取会话变量,但是此服务器是 Ubuntu 10.04。

知道下一步该做什么吗?

【问题讨论】:

  • 您尝试设置suhosin.session.cryptdocroot 3 次是否有任何特殊原因?
  • 感谢您选择这个,第一个应该是 suhosin.session.encrypt,其他的是 cookie.cryptdocroot, session.cryptdocroot。我已经更新了现场网站上的脚本并重新测试。问题是我无法关闭任何这些设置。为什么?
  • session_set_cookie_params() 在 session_start() 之后没有任何意义。是 session_start() 写入设置会话 ID cookie 的标头。

标签: php session suhosin


【解决方案1】:

您尝试更改的选项(例如,suhosin.cookie.cryptdocroot)会影响 Suhosin 在脚本开始运行之前所做的事情。因此,在运行时更改它们没有意义 - 您需要将它们设置为 php.ini 或类似名称。

【讨论】:

  • 谢谢,它们是在 php.ini 中设置的——但它们可能不是我在两者之间失去会话的原因。
【解决方案2】:

我最近在将 HTTP 和 HTTPS VirtualHost 文件合并为一个并出于安全原因将 apache 服务器更改为 MPM-ITK 时自己打破了这一点。

在合并的 VirtualHost 文件中

<VirtualHost 120.138.18.91:80>
    ServerName www.theparentingplace.com

    DocumentRoot /var/www/www.theparentingplace.com/joomla
    CustomLog /var/log/apache2/www.theparentingplace.com-access.log   combined
    ErrorLog /var/log/apache2/www.theparentingplace.com-error.log

<IfModule mpm_itk_module>
    AssignUserId www-theparentingplace www-theparentingplace
</IfModule>

    RewriteEngine On
    RewriteCond %{QUERY_STRING} ^.*=(ht)|(f)+(tp)+(://|s://)+.*(\?\?)+
    RewriteRule .* http://gggooooooglleee.com/ [R,L]

    <FilesMatch "images/\.(asp|php|php5|pl)$">
        Deny from all
    </FilesMatch>
</VirtualHost>

<VirtualHost 120.138.18.91:443>
ServerName www.theparentingplace.com
    DocumentRoot /var/www/www.theparentingplace.com/joomla

CustomLog /var/log/apache2/www.theparentingplace.com-ssl-access.log combined
ErrorLog /var/log/apache2/www.theparentingplace.com-ssl-error.log

<IfModule mpm_itk_module>
    AssignUserId www-theparentingplace www-theparentingplace
</IfModule>

SSLEngine on
SSLCertificateFile /etc/apache2/ssl/www.theparentingplace.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
    SSLCertificateChainFile /etc/apache2/ssl/www.theparentingplace.com.ca.crt

BrowserMatch ".*MSIE.*" \
    nokeepalive ssl-unclean-shutdown \
    downgrade-1.0 force-response-1.0

   RewriteEngine On
   RewriteCond %{QUERY_STRING} ^.*=(ht)|(f)+(tp)+(://|s://)+.*(\?\?)+
   RewriteRule .* http://gggooooooglleee.com/ [R,L]

   <FilesMatch "images/\.(asp|php|php5|pl)$">
       Deny from all
   </FilesMatch>
</VirtualHost>

我忘记添加了

<IfModule mpm_itk_module>
    AssignUserId www-theparentingplace www-theparentingplace
</IfModule>

阻止安全站点部分,因此 https 站点无法读取会话文件。

感谢 Brian North 让我想到检查是否可以强制使用 https 的 session_id(我无法使用错误的配置)

【讨论】:

    【解决方案3】:

    session_start() 必须在 之前调用 - 所以在你的 if ($_GET['is'] == 'set') 块中,print 调用会阻止你的会话开始。没有它,$_SESSION['test'] 将永远不会持续足够长的时间让您的if ($_SESSION['test'] == 'abc') 块测试为真。 编辑: 必须在任何输出之前发送所有标头(这也是之前必须调用 session_start() 的原因) - 所以您在 ini_set 块中的 print 调用仍会阻止您的 header( 'location' ... )称呼。如果您需要查看ini_set() 返回的内容,请通过error_log( "Old 'suhosin.session.encrypt': " . print_r( ini_set('suhosin.session.encrypt', 0), true) ); 为每个配置将其值输出到错误日志中。或者缓存结果并print它们发送任何可能的标头之后。

    在 http 和 https 之间传输也会丢失会话变量,因为它们会启动单独的会话。这个问题应该涵盖您的其余问题。 Session lost when switching from HTTP to HTTPS in PHP

    对于您的 suhosin... ini 设置,ini_set 将返回 previous 值 - 因此,如果 ini 配置之前为 false,您将获得 false,即使调用成功了。

    【讨论】:

    • 谢谢,已将 session_start 移至顶部。这 3 个 suhosin 设置实际上在 php.ini 中设置为 Off,因此您可能完全正确。我可能是用suhosin追错了,我要解决的问题是http和https之间的会话丢失了。
    • 如果 ini.php 中的这些设置关闭,那么 ini_set() 函数将为它们返回 false。为了在 http 和 https 之间保持相同的会话,问题是 PHP 并且您的服务器将它们视为启动单独的会话。我在上次编辑中包含的问题/答案解决了这个问题。基本上,您必须在进行切换时手动传递会话 ID。
    • 我看过那个答案,但它根本不正确。除非设置附加参数,否则 HTTP 和 HTTPS 之间不会丢失 Session 变量。我在另一台服务器上运行它,会话不会丢失:acgedu.com/http_https_session_test.php P.S.看到你的最后评论,但不正确 IMO
    • 您的session_set_cookie_params 调用具有$domain 参数作为'' - 当您传递它“.theparentingplace.com”时会发生什么? session_set_cookie_params ( '3600','/','.theparentingplace.com',false, false );
    • 没有变化,请参阅已编辑的问题以仔细检查我的理解
    猜你喜欢
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    相关资源
    最近更新 更多