From 825db7f95912488377b144c830bd453914546516 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Mon, 24 Aug 2026 13:30:00 -0400 Subject: [PATCH] ext/session: Abort strict-mode re-creation when create_sid() fails When a save handler rejects the session ID under session.use_strict_mode, php_session_initialize() papered over a failing s_create_sid() by generating an internal ID and carrying on, so reset_id()'s Set-Cookie and SID side effects ran for a session that never started, and a second failure left PS(id) NULL. Mirror the primary no-ID branch: abort the session, throw when no exception is pending, and return FAILURE. Sibling sites audited, session_regenerate_id() and session_create_id() already NULL-check with their own error paths. --- NEWS | 4 ++ ext/session/session.c | 6 ++- ...tart_strict_recreate_create_sid_fails.phpt | 49 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 ext/session/tests/user_session_module/session_start_strict_recreate_create_sid_fails.phpt diff --git a/NEWS b/NEWS index e7f45c810b23..8d5bf4716939 100644 --- a/NEWS +++ b/NEWS @@ -66,6 +66,10 @@ PHP NEWS . Fixed a heap over-read in the interactive shell prompt when cli.prompt is set to an empty string. (Ilia Alshanetsky) +- Session: + . Fixed session_start() continuing after a failed create_sid() when + session.use_strict_mode rejects the supplied ID. (Ilia Alshanetsky) + - Sockets: . Fixed socket_select() silently truncating sets larger than FD_SETSIZE on Windows. (David Carlier) diff --git a/ext/session/session.c b/ext/session/session.c index 2073ea55fe1f..bed25c2ebba6 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -465,7 +465,11 @@ static zend_result php_session_initialize(void) /* {{{ */ } PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { - PS(id) = php_session_create_id(NULL); + php_session_abort(); + if (!EG(exception)) { + zend_throw_error(NULL, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path)); + } + return FAILURE; } if (PS(use_cookies)) { PS(send_cookie) = 1; diff --git a/ext/session/tests/user_session_module/session_start_strict_recreate_create_sid_fails.phpt b/ext/session/tests/user_session_module/session_start_strict_recreate_create_sid_fails.phpt new file mode 100644 index 000000000000..3c3ac1dea327 --- /dev/null +++ b/ext/session/tests/user_session_module/session_start_strict_recreate_create_sid_fails.phpt @@ -0,0 +1,49 @@ +--TEST-- +session_start() strict mode re-creation must abort when create_sid fails +--INI-- +session.use_trans_sid=1 +session.use_only_cookies=0 +error_reporting=E_ALL & ~E_DEPRECATED +--EXTENSIONS-- +session +--FILE-- + true])); +} catch (Throwable $e) { + echo $e::class, ': ', $e->getMessage(), PHP_EOL; +} + +var_dump(session_status() === PHP_SESSION_ACTIVE); +var_dump(defined('SID')); + +?> +--EXPECT-- +Error: Session id must be a string +bool(false) +bool(false)