登录成功后必须立即调用session_regenerate_id(true),在写入$_SESSION敏感数据后、重定向前执行,强制删除旧会话文件以防御会话固定;登录页不应提前启动会话,需禁用透明传输、校验并拦截手动传参的PHPSESSID,同步收紧Cookie属性与会话配置。

登录成功后不调用 session_regenerate_id(true),就等于把登录凭证直接递给攻击者。
登录验证通过后必须立刻执行 session_regenerate_id(true)
这不是可选操作,而是防御会话固定的唯一有效动作。它在身份确认无误的瞬间切断旧 ID 与用户身份的绑定。
- 必须放在
$_SESSION写入敏感数据(如user_id)之后、重定向之前 -
true参数不可省略:它强制删除旧会话文件,否则攻击者仍可能读取刚写入的登录态 - 不能在
session_start()后立即调用,也不能在密码错误时调用——那会暴露新 ID 给未授权用户 - 若用了 Redis 等自定义 session 处理器,需确认其支持
session_regenerate_id()的清理逻辑
登录页本身不能提前分配会话 ID
很多项目一打开 login.php 就执行 session_start(),等于帮攻击者铺好了路。
审查 Remix v2 代码中的 v1 形态 meta 导出(v2 中为破坏性变更),cookie 安全漏洞(httpOnly、secure、密钥轮换),认证门位于错误层级,以及其他
- 未登录态页面尽量避免启动会话;真需要存 CSRF Token 或失败计数,应在登录前先
session_destroy()+session_unset(),再session_start() - 禁用透明传输:
ini_set('session.use_trans_sid', '0'),防止 ID 泄露在 URL 中 - 主动拦截手动传参:
if (isset($_GET['PHPSESSID'])) { session_destroy(); exit; } - 开发环境测试时拼
?PHPSESSID=xxx很方便,上线前必须关掉——这等于把钥匙挂在门把手上
Cookie 属性和会话配置必须同步收紧
只换 ID 不够,旧 Cookie 还能被浏览器自动发送,攻击者就还能续命。
立即学习“PHP免费学习笔记(深入)”;
-
session_set_cookie_params()必须在session_start()前调用,参数包括secure、httponly、samesite - 启用严格模式:
ini_set('session.use_strict_mode', '1'),拒绝未知 ID 的会话初始化 - 关键 php.ini 配置:
session.use_only_cookies = 1、session.cookie_httponly = 1、session.cookie_secure = 1 - 注意
session.cookie_samesite在 PHP 7.3+ 才支持数组写法,低版本需用字符串
真正容易被忽略的是:攻击者往往从登录页开始布设陷阱,而开发者只盯着“登录成功后”这一段逻辑。会话固定常和会话劫持组合利用,防御必须覆盖整个会话生命周期——从第一个请求开始,到每一次敏感操作前。


















