会话 id 太长或包含非法字符,有效字符为 a-z、A-Z、0-9 和 '-,'

Posted

技术标签:

【中文标题】会话 id 太长或包含非法字符,有效字符为 a-z、A-Z、0-9 和 \'-,\'【英文标题】:The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'会话 id 太长或包含非法字符,有效字符为 a-z、A-Z、0-9 和 '-,' 【发布时间】:2011-03-12 06:38:01 【问题描述】:

如何解决:

警告: session_start() [function.session-start]: session id太长或包含非法字符,有效字符为az, AZ, 0-9 和'-,' in .....在线3

警告:session_start() [function.session-start]:无法发送会话 cookie - 标头已由第 3 行 ..... 中的(输出开始于......:3)发送

警告:session_start() [function.session-start]:无法发送会话缓存限制器 - 第 3 行的 ..... 中已发送标头(输出开始于.....:3)

【问题讨论】:

会话 ID 中没有非法字符? 【参考方案1】:

这是一个信息漏洞:恶意攻击者可能会更改cookie并将非法字符分配给phpSESSID以暴露此PHP警告,其中实际上包含文件路径和用户名等多汁信息!

【讨论】:

我的会话似乎处于这种“调查”之下,我很欣赏这是一个旧答案,但是您对如何锁定此信息有任何指示吗?我的错误日志只对服务器端开放,而不是更广泛的网络,我需要/应该做更多吗? @Martin 要锁定此错误或保护您的脚本,您必须在 session_start() 之前检查 cookie,检查变量 $_COOKIE['PHPSESSID']) 是否包含非法字符,如果它那么你的脚本应该重新加载页面或者只是删除它们,如果没有,那么你可以安全地继续。 值得一提的是owasp.org docs:只需关闭错误报告功能,您的代码就不会出现错误,即可防止此漏洞。 【参考方案2】:

查看此session_start() discussion 以获得解决方法:

session_start() 如果 PHPSESSID 包含非法字符,则生成警告

警告:session_start() [function.session-start]:会话id包含非法字符,有效字符是/home/para/dev/mon_site/header中的az、AZ、0-9和'-,'。 php 在第 17 行

为了避免我写了这个:

   <?php
        function my_session_start()
        
            if (ini_get('session.use_cookies') && isset($_COOKIE['PHPSESSID'])) 
                $sessid = $_COOKIE['PHPSESSID'];
             elseif (!ini_get('session.use_only_cookies') && isset($_GET['PHPSESSID'])) 
                $sessid = $_GET['PHPSESSID'];
             else 
                session_start();
                return false;
            

           if (!preg_match('/^[a-z0-9]32$/', $sessid)) 
                return false;
            
            session_start();

           return true;
        
    ?>

【讨论】:

你如何在PHPSESSID 中得到非法字符?不是PHP自动生成的吗? 它们是,但是将您链接到生成的会话 ID 的 cookie 是客户端。如果该 cookie 更改为无效格式(有人试图利用某些东西)PHP 会注意到它。 很好的提示,但是如果有人依赖 session_autostart 功能...如何用您在此处建议的功能覆盖 session_start() 功能? 您是否在正则表达式中缺少-,因为这是一个有效字符。 原始答案引入了一个潜在的安全漏洞 - 我已经编辑修复它。【参考方案3】:

有针对此问题的错误报告 (https://bugs.php.net/bug.php?id=68063)

您可以检查您的 session_start 是否成功并在需要时生成 id:

$ok = @session_start();
if(!$ok)
session_regenerate_id(true); // replace the Session ID
session_start(); 

【讨论】:

它对我有用,让我知道脚本是保存还是 melicious? 我试过这个并得到:session_regenerate_id(): Cannot regenerate session id - session is not active in FILE on line X 后跟与问题标题相同的错误... @conner_bw 这似乎是另一个问题,但请检查此问题:***.com/questions/31436949/… 这似乎相似并且有一个可接受的答案。【参考方案4】:

我编辑了 Andron's previous solution! (修复返回值)并添加了 my_session_start() 的评估输出。以前的解决方案解决了错误消息的问题,但我需要启动会话。

/**
 * @return boolean return TRUE if a session was successfully started
 */        
function my_session_start()

      $sn = session_name();
      if (isset($_COOKIE[$sn])) 
          $sessid = $_COOKIE[$sn];
       else if (isset($_GET[$sn])) 
          $sessid = $_GET[$sn];
       else 
          return session_start();
      

     if (!preg_match('/^[a-zA-Z0-9,\-]22,40$/', $sessid)) 
          return false;
      
      return session_start();


if ( !my_session_start() ) 
    session_id( uniqid() );
    session_start();
    session_regenerate_id();

【讨论】:

【参考方案5】:

我建议使用“更正确”版本的函数。

几个注意事项:

    更正确的正则表达式(允许 a-z A-Z 0-9 、(逗号)和 -(减号)范围内的字符)如 here 所述。 正则表达式取决于 php ini 设置,如 here 和 here 所述。 使用会话名称方法

所以更新后的版本是这样的:

<?php
    function my_session_start()
    
        $sn = session_name();
        if (isset($_COOKIE[$sn])) 
            $sessid = $_COOKIE[$sn];
         else if (isset($_GET[$sn])) 
            $sessid = $_GET[$sn];
         else 
            session_start();
            return false;
        

       if (!preg_match('/^[a-zA-Z0-9,\-]22,40$/', $sessid)) 
            return false;
        
        session_start();

       return true;
    
?>

【讨论】:

这应该检查 PHP ini 设置。在大多数健全的配置中,会话永远不会在 GET 参数中进行,因此无需检查它们。【参考方案6】:

如果您不关心其他用户(例如:如果它是私有接口),只需检查您的浏览器,找到 cookie PHPSESSID(或您给它的名称),删除它,然后刷新。

【讨论】:

【参考方案7】:

我想出了这个简单的方法,只需尝试捕获会话开始,如果有问题重新生成会话。

try 
   session_start();
 catch(ErrorExpression $e) 
   session_regenerate_id();
   session_start();
 

【讨论】:

您无法使用 try-catch 捕获警告。

以上是关于会话 id 太长或包含非法字符,有效字符为 a-z、A-Z、0-9 和 '-,'的主要内容,如果未能解决你的问题,请参考以下文章

Mac下关于——你不能拷贝项目“”,因为它的名称太长或包括的字符在目的宗卷上无效。文件的删除

session_start() 有关非法字符、空会话 ID 和失败会话的问题

比较版本返回太长或太短异常

仅保留字符串中的有效字符

text 错误:错误:“T”不是有效的基于文件的资源名称字符:基于文件的资源名称必须仅包含小写的a-z,0-9或

SQL 对于字符串来说太长了