Skip to main content
← All articles
php

PHP 8.6 flips three session defaults — Drupal already did

PHP 8.6 flips three session defaults — Drupal already did

PHP 8.6 is going to flip three session defaults, and the headline reaction — "finally, secure by default!" — is right but aimed at the wrong audience. If you run Drupal, 8.6 changes nothing about how your web requests handle sessions, because Drupal already does all three. The posts that matter are the stray bits of PHP sharing the box with it. Let me separate the two.

What changes

The RFC is "Secure Session Configuration Defaults" by Jörg Sowa, Accepted, each setting voted separately and near-unanimously (strict mode 27–0, httponly 26–0, samesite 26–0, around 3–17 May 2026). From the PHP-8.6 UPGRADING file:

SettingOldNew
session.use_strict_mode01
session.cookie_httponly01
session.cookie_samesite(unset)Lax

In plain terms: strict mode makes PHP reject a client-supplied session ID that has no stored session behind it (kills session fixation via planted IDs); httponly stops document.cookie from reading the session cookie; SameSite=Lax tells the browser not to attach the cookie on cross-site requests except top-level navigations. PHP 8.6.0 RC3 was tagged 8 Oct 2026 (a packaging slip skipped RC1); GA is scheduled for 19 Nov 2026.

Drupal got here first

I went and checked my own tree (Drupal 11.3.10) rather than trust memory:

  • DrupalKernel.php calls ini_set('session.use_strict_mode', '1') and ini_set('session.cookie_httponly', '1') — but only when PHP_SAPI !== 'cli'.
  • core.services.yml sets cookie_samesite: Lax under session.storage.options.

So for a Drupal web request, 8.6's new defaults land on settings Drupal already forced. That's the quiet truth of this release for us: PHP is catching up to what your framework has done for years. Nice, but not an action item.

The danger isn't Drupal. It's the admin.php a predecessor left in a subfolder, the standalone vendor tool on the same vhost, the cron script that calls session_start() — none of which got Drupal's hardening, and all of which 8.6 will quietly change under them.

Where it actually bites

Two blind spots. First, CLI: Drupal's ini_sets are explicitly skipped when PHP_SAPI === 'cli', so any script that leans on old session defaults from the command line is on its own. Second, and more likely to ruin a morning: SSO. The RFC itself warns that with Lax, "flows such as SP-initiated SAML SSO may break," and suggests SameSite=None; Secure on those endpoints or a token-based flow.

Here's where I have to be honest about the limits of my own reasoning. My mental model says Lax only blocks the browser from sending the existing cookie on a cross-site POST, while the SSO response can still set a fresh one — so an ACS endpoint receiving the IdP's POST might be fine, or might not, depending on exactly which hop needs the pre-existing session cookie. MDN confirms Lax excludes the cookie on cross-site POST; it did not confirm the Set-Cookie side for me. So I'm not going to assert your SAML will or won't break. I'm going to tell you to test it: spin up 8.6 RC3 in a DDEV sidecar and run your actual SSO flow against it before 19 November. Don't take my arithmetic, take your own ACS logs.

While you're upgrading anyway

8.6 carries a pile of smaller BC breaks worth a grep: trim()/ltrim()/rtrim() now strip form feed by default; preg_grep() returns false on execution errors; many file and path functions throw ValueError on NUL bytes; spl_object_hash() is deprecated; and return inside finally is deprecated. The UPGRADING file also notes a session-handler deprecation for handlers lacking create_sid() or validateId() — I didn't confirm whether Drupal's SessionHandler is affected, so add that to your own check list rather than my fact list.

The takeaway

For a Drupal-only box, 8.6's session changes are a non-event for web traffic and a mild cleanup everywhere else. Spend your upgrade budget on the two things it can actually break: CLI scripts that assumed the old defaults, and any cross-site auth flow. Test those against RC3 now, while "it broke" is a DDEV log and not a support ticket.

Links

BM
Blue Moose
The moose behind Blue Moose. Full-stack PHP developer — Drupal by day, Symfony by night, tests always.