PHP 中会话名称的限制是啥?
Posted
技术标签:
【中文标题】PHP 中会话名称的限制是啥?【英文标题】:What are the limits on session names in PHP?PHP 中会话名称的限制是什么? 【发布时间】:2021-02-05 18:16:45 【问题描述】:The php docs on session_name()
说:
它应该只包含字母数字字符;它应该简短且具有描述性(即对于启用了 cookie 警告的用户)。 ...会话名称不能仅由数字组成,必须至少存在一个字母。否则每次都会生成一个新的会话 ID。
所以很明显你必须有一些非数字的东西,但不清楚你不能有哪些字符。 cookie 规范本身拒绝 ()<>@,;:\"/[]?=
,但这仍然留下了其他可能被允许但不是严格字母数字的。这很重要,因为 cookie security prefixes 在 __Secure-PHPSESSID
之类的名称中使用 -
和 _
。所以我翻遍了in the PHP source code at the session_name function——但除了检查它是一个字符串之外,我看不到它有什么作用。在实践中,它工作得很好,但我会更清楚地知道为什么!例如,这有效:
session_name('__Secure-PHPSESSID');
session_start();
$_SESSION['test'] = $_SESSION['test'] . "\n" . rand(0,100);
var_dump($_SESSION);
那么 PHP 会话名称的实际限制是什么?
【问题讨论】:
它在那里说:“只有字母数字字符”。只是字母和数字,而不是所有数字。 我知道,这就是我引用文档的原因。请阅读问题 - 它适用于包含-
和 _
的会话名称,所以我想确切地了解约束是什么,而不仅仅是文档所说的,因为这些显然不是一定是同一件事。
它没有强制要求,我认为它只是预测可能发生的问题,所以它指定了一个保守的要求。
代码中可能存在实际限制,并且他们从未更新过文档。 OTOH,他们也可能允许稍后在代码中添加限制,您不应该依赖当前的实现。
参见文档中的this comment,但它已有 15 年历史,可能已过时。
【参考方案1】:
我对此有所了解。会话名称的规则在this validation function 中定义,它允许[a-zA-Z0-9,-]1,256
(但不是仅限数字)。除了字母数字之外,您还可以在会话名称中使用逗号和破折号,因此文档是错误的。此函数从内部 session_create_id
函数调用,如果会话名称未通过该验证,则 triggers a warning。
尽管如此,当传入包含_
的会话名称时不会触发警告。这是可以证明的:
<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
session_name('__Secure-MySession');
session_start();
if (!array_key_exists('test', $_SESSION))
$_SESSION['test'] = '';
$_SESSION['test'] .= "\n" . rand(0,100);
var_dump($_SESSION);
echo session_name();
这很完美,不会触发任何错误或警告,并显示一个不断增长的随机数列表(表明会话存储正在工作,因此 cookie 也是如此),第二个不带参数的 session_name
调用显示了会话我们设置的名称:
__Secure-MySession
并且 HTTP 标头显示该脚本设置了一个名为 __Secure-MySession
的 cookie:
我还尝试将会话命名为 My_Session
,以防 PHP 寻找明确的 __Session-
前缀,但这也很好用。 #
或 (
等其他字符也不会触发错误;在这些情况下,会话名称是 URL 编码的,它看起来非常像很久以前修复的 this bug。正如预期的那样,123,
可以工作,但也可以对逗号进行 URL 编码。
因此,虽然这表明在会话名称中包含 _
可以正常工作,但我无法告诉您原因。我也在其他地方问过,如果我发现了,我会更新这个问题!
巧合的是,draft 06 of RFC6265bis expires today。
【讨论】:
以上是关于PHP 中会话名称的限制是啥?的主要内容,如果未能解决你的问题,请参考以下文章