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

Session 会话id太长或包含非法字符,有效字符为a-z、a-z、0-9和';-';,session,php,Session,Php,如何解决: 警告:会话_start()[function.session start]:会话id太长或包含非法字符,有效字符为a-z、a-z、0-9和“-,”in。。。。。在线3 警告:session_start()[function.session start]:无法发送会话cookie-标头已由…发送(输出开始于…:3)。。。。。在线3 警告:session_start()[function.session start]:无法发送会话缓存限制器-已在…..中发送了标头(输出从…..开始:3)

如何解决:

警告:会话_start()[function.session start]:会话id太长或包含非法字符,有效字符为a-z、a-z、0-9和“-,”in。。。。。在线3

警告:session_start()[function.session start]:无法发送会话cookie-标头已由…发送(输出开始于…:3)。。。。。在线3

警告:session_start()[function.session start]:无法发送会话缓存限制器-已在…..中发送了标头(输出从…..开始:3)。。。。。在线3

请查看以下内容,了解解决方案:

session\u start()
如果PHPSESSID包含非法字符,则生成警告

警告:session_start()[function.session start]:会话id包含非法字符,第17行的/home/para/dev/mon_site/header.php中的有效字符为a-z、a-z、0-9和“-、”

为了避免这种情况,我写了以下内容:

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


这是一个信息漏洞:恶意攻击者可能会更改Cookie并将非法字符分配给PHPSESSID以暴露此PHP警告,该警告实际上包含丰富的信息,如文件路径和用户名

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

几点注意:

  • 更正确的正则表达式(允许范围为a-z a-z 0-9,(逗号)和-(减号))如前所述。
    正则表达式取决于PHPINI设置,如所述和
  • 使用会话名称方法
  • 更新后的版本如下所示:

    <?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;
        }
    ?>
    
    
    
    我编辑过!(修复返回值)并添加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();
    }
    

    如果您不关心其他用户(例如:如果它是一个私有界面),只需检查您的浏览器,找到cookie PHPSESSID(或您提供的名称),删除它,然后刷新即可。

    此问题有错误报告()

    您可以检查会话启动是否成功,并根据需要生成id:

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

    我想出了这个简单的方法,只要尝试捕捉会话开始,如果出现问题,就重新生成会话

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

    会话id中没有非法字符?首先,如何在
    PHPSESSID
    中使用非法字符?它们不是由PHP自动生成的吗?它们是,但将您链接到生成的会话id的cookie是客户端。如果cookie更改为无效格式(有人试图利用某个漏洞),PHP会注意到它。很好的提示,但如果有人依赖session_autostart功能。。。如何用您在此处建议的函数重写会话_start()函数?正则表达式中是否缺少
    -
    ,因为这是一个有效字符。原始答案引入了一个潜在的安全漏洞-我已编辑以修复它。它对我有效,让我知道脚本是否已保存或是否合理?我尝试了此操作并获得:
    session\u regenerate\u id():无法重新生成会话id-第X行的文件中会话未处于活动状态,随后出现与问题标题相同的错误…@conner_bw这似乎是另一个问题,但请检查此问题:这似乎类似,并且有一个可接受的答案。我的会话似乎正在进行这种“调查”,我很感激这是一个旧答案,但是你有什么关于如何锁定这些信息的建议吗?我的错误日志只对服务器端开放,而不是对更广泛的web开放,我需要/应该做更多吗?@Martin要锁定此错误或保护您的脚本,您必须在会话_start()之前检查COOKIE,检查变量$_COOKIE['PHPSESSID']),如果它包含非法字符,则您的脚本应重新加载页面或删除它们,如果没有,那么您可以安全地继续。值得一提的是:只需关闭错误报告,这样您的代码就不会吐出错误,就可以防止此漏洞。您无法使用try-catch捕获警告。这应该检查PHP ini设置。在大多数sane配置中,会话从不保存在GET参数中,因此不需要检查它们。