session.use_strict_mode启用后,php拒绝未在服务端注册的会话id,防止会话固定攻击;需在session_start()前设置,配合session_regenerate_id(true)和cookie安全策略使用。

session.use_strict_mode 是什么
这个配置项启用后,PHP 会拒绝任何未在服务端注册过的会话 ID。也就是说,如果攻击者提前构造一个链接如 example.com/login.php?PHPSESSID=abc123 发给用户,而该 abc123 并非由当前服务器生成并记录的合法会话 ID,那么即使用户点击并开始访问,PHP 也不会加载它,而是立即丢弃并生成一个全新的、随机的会话 ID。
为什么旧 sessionid 复用会出问题
不开启 strict mode 时,PHP 默认接受任意格式合法的 SID(比如长度对、字符合规),哪怕这个 ID 从未被创建过。攻击者可预先生成一批可能的 ID(或直接伪造一个看似合理的),诱导用户带着它访问登录页——一旦用户成功登录,服务器就将用户身份绑定到这个攻击者已知的 ID 上,完成会话固定攻击。
- 攻击者能控制登录前的会话上下文
- 用户登录后,攻击者立刻用相同 ID 访问后台,获得等效权限
- 尤其危险于登录页未做会话清理、也未调用 session_regenerate_id(true) 的场景
开启 strict mode 的实操要点
必须在 session_start() 调用之前设置,且不能有任何输出(包括空格、BOM、echo):
- ini_set('session.use_strict_mode', '1'); —— 字符串 '1' 或整数 1 均可,但建议统一用字符串保持兼容性
- 搭配 ini_set('session.use_only_cookies', '1'); 禁用 URL 传参,避免 SID 泄露到日志或 Referer
- 同时关闭 ini_set('session.use_trans_sid', '0'); 防止自动在 URL 后追加 ?PHPSESSID=xxx
- 若部署在 HTTPS 环境,务必加 ini_set('session.cookie_secure', '1'); 和 ini_set('session.cookie_httponly', '1');
这些设置应统一放在项目入口文件(如 index.php 或框架的初始化脚本)最顶部,在任何业务逻辑、路由判断、甚至 error_reporting() 之前执行。
配合登录流程才能真正防住固定攻击
strict mode 单独开启只能防“未注册 ID”的复用,但它不解决“已存在的旧 ID 被继续使用”的问题。所以必须和登录动作联动:
- 用户提交账号密码并校验通过后,**立即**执行 session_regenerate_id(true)
- true 参数表示删除旧会话存储文件,彻底切断攻击者持有的旧 ID 关联
- 此时新会话 ID 已由 strict mode 保障为“仅服务端生成”,旧 ID 即使被截获也无法再加载有效数据
- 建议在登录成功后的第一行 PHP 代码就调用该函数,不要延迟到跳转或写入 $_SESSION 之后
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











