Commit 66d496061c5 for php.net
commit 66d496061c5078e891a2b8e99ea11e28b2d04060
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Tue Aug 18 21:41:16 2026 -0400
Document and test SessionHandler::validateId() (#23071)
The method landed in 6901c87aeab with no NEWS or UPGRADING entry. Add
both, and a test pinning that an unknown ID is regenerated rather than
adopted when the built-in handler runs with session.use_strict_mode=1.
Closes GH-23071
diff --git a/NEWS b/NEWS
index 494eede7486..b750a036ed3 100644
--- a/NEWS
+++ b/NEWS
@@ -61,6 +61,8 @@ PHP NEWS
- Session:
. Fixed bug GH-23056 (missing handler name in session write warning).
(lazerg)
+ . SessionHandler::validateId() is now implemented, so
+ session.use_strict_mode applies to the built-in handler. (Girgias)
- Zip:
. Fixed bug GH-17787 (ZipArchive stream stops reading early when the archive
diff --git a/UPGRADING b/UPGRADING
index e8eec0d0bbd..d6e24356ee3 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -162,6 +162,12 @@ PHP 8.6 UPGRADE NOTES
explicitly set this to "None" (and also set session.cookie_secure
to 1).
RFC: https://wiki.php.net/rfc/session_security_defaults
+ . SessionHandler::validateId() has been added and delegates to the
+ configured save handler. A subclass that declares validateId() without
+ a return type now emits a deprecation notice for the tentative bool
+ return type. A subclass that overrides open() without calling
+ parent::open() keeps its previous behavior and emits a warning when an
+ ID is validated.
- Shmop:
. shmop_open() now raises a ValueError when the $key argument is outside the
diff --git a/ext/session/tests/user_session_module/session_strict_mode_sessionhandler.phpt b/ext/session/tests/user_session_module/session_strict_mode_sessionhandler.phpt
new file mode 100644
index 00000000000..13099c97cc2
--- /dev/null
+++ b/ext/session/tests/user_session_module/session_strict_mode_sessionhandler.phpt
@@ -0,0 +1,44 @@
+--TEST--
+session.use_strict_mode regenerates an unknown ID for the built-in SessionHandler
+--EXTENSIONS--
+session
+--INI--
+session.save_handler=files
+session.use_strict_mode=1
+session.use_cookies=0
+session.cache_limiter=
+session.gc_probability=0
+--FILE--
+<?php
+$save_path = sys_get_temp_dir() . '/sess_strict_mode_sessionhandler';
+@mkdir($save_path);
+ini_set('session.save_path', $save_path);
+
+$known_id = 'knownfilesessionid';
+file_put_contents($save_path . '/sess_' . $known_id, 'value|s:5:"files";');
+
+session_set_save_handler(new SessionHandler, true);
+
+session_id($known_id);
+session_start();
+var_dump(session_id() === $known_id);
+var_dump($_SESSION['value']);
+session_write_close();
+
+session_id('attackerchosensessionid');
+session_start();
+var_dump(session_id() === 'attackerchosensessionid');
+session_write_close();
+?>
+--CLEAN--
+<?php
+$save_path = sys_get_temp_dir() . '/sess_strict_mode_sessionhandler';
+foreach (glob($save_path . '/sess_*') as $file) {
+ unlink($file);
+}
+rmdir($save_path);
+?>
+--EXPECT--
+bool(true)
+string(5) "files"
+bool(false)