会话 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 和失败会话的问题