Session 安全

  • 有很多种方式都可以导致会话 ID 被泄露给第三方。 例如,JavaScript 注入,URL 中包含会话 ID,数据包侦听, 或者直接访问你的物理设备等。
  • 如果会话 ID 被泄漏给第三方, 那么他们就可以访问这个会话 ID 可以访问的全部资源。

  • 首先,如果在 URL 中包含了会话 ID, 并且访问了外部的站点, 那么你的会话 ID 可能在外部站点的访问日志中被记录(referrer 请求头)。 另外,攻击者也可以监听你的网络通信,如果通信未加密, 那么会话 ID 将会在网络中以明文的形式进行传输。 针对这种情况的解决方案就是在服务端配置 SSL/TLS, 另外,使用 HSTS 可以达到更高的安全性。

  • 新增加了一个配置项: session.use_strict_mode。 当启用这个配置项,并且你所用的会话存储处理器支持的话,未经初始化的会话 ID 会被拒绝, 并为其生成一个全新的会话,这可以避免攻击者使用一个已知的会话 ID 来进行攻击。 例如,攻击者可以通过邮件给受害者发送一个包含会话 ID 的链接: http://example.com/page.php?PHPSESSID=123456789。 如果启用了 session.use_trans_sid 配置项, 那么受害者将会使用攻击者所提供的会话 ID 开始一个新的会话。 如果启用了 session.use_strict_mode 选项,就可以降低风险。

  • 虽然 session.use_strict_mode 配置项可以降低风险,但是还不够。为了确保会话安全,开发者还需要使用 session_regenerate_id() 函数。

  • session.use_strict_mode=On

    • 虽然启用 session.use_strict_mode 是必不可少的,但是默认情况下,这个配置项是未启用的。
    • 此设置防止会话模块使用未初始化的会话 ID。 也就是说, 会话模块仅接受由它自己创建的有效的会话 ID, 而拒绝由用户自己提供的会话 ID。
    • 攻击者可以自行设置 cookie 或者使用 JavaScript 注入的方式 来设置会话 ID 进行攻击。 启用 session.use_strict_mode 配置项 可以阻止使用未经会话模块初始化的会话 ID。
    • 攻击者可以使用自己的设备产生会话 ID,也可以使用受害者的会话 ID。 攻击者也可以通过一些后续操作保证会话活跃。 因此,启用 session.use_strict_mode 配置项 可以降低这种风险。
  • 会话 ID 重生机制可以有效的降低会话被窃取的风险, 所以,必须周期性的调用 session_regenerate_id() 函数 来重新生成会话 ID, 例如,对于机密内容,每隔 15 分钟就重新生成会话 ID。 这样一来,即使会话 ID 被窃取, 那么攻击者所得到的会话 ID 也会很快的过期, 如果他们进一步访问,就会产生对过期会话数据访问的错误。

  • 当用户成功通过认证之后,必须为其重新生成会话 ID。 并且,必须在向 $_SESSION 中保存用户认证信息之前 调用 session_regenerate_id() 函数( session_regenerate_id() 函数 会自动将重生之前的会话数据保存到新生成的会话)。 请确保只有新的会话包含用户认证信息。

  • 开发者不可过分依赖 session.gc_maxlifetime 配置项。 因为攻击者可以在受害者的会话过期之前访问系统, 并且维持这个会话的活动,以保证这个会话不会过期。

  • 默认情况下,session_regenerate_id() 函数 不会删除旧的会话, 所以即使重生了会话 ID,旧的会话可能还是可用的。开发者需要使用时间戳等机制, 来确保旧的会话数据不会再次被访问。

  • session.cookie_httponly=On,禁止 JavaScript 访问会话 cookie。 此设置项可以保护 cookie 不被 JavaScript 窃取。