Commit 0870487b625 for php.net
commit 0870487b6256cbfbc12134cd52c599a92c1ac160
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Wed Jul 29 12:03:18 2026 -0400
ext/session: report a rejected session cookie header
php_session_send_cookie() discarded the result of sapi_add_header_ex()
and always returned SUCCESS. When the SAPI refuses a Set-Cookie header
carrying CR or LF, the warning it emits can reach a userland error
handler that calls session_destroy(), and php_session_reset_id() then
appends the released PS(id). Return what sapi_add_header_ex() reports so
the caller stops before touching session state again.
Closes GH-22923
diff --git a/ext/session/session.c b/ext/session/session.c
index f03813c791d..2073ea55fe1 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -1499,10 +1499,10 @@ static zend_result php_session_send_cookie(void) /* {{{ */
php_session_remove_cookie(); /* remove already sent session ID cookie */
/* 'replace' must be 0 here, else a previous Set-Cookie
header, probably sent with setcookie() will be replaced! */
- sapi_add_header_ex(estrndup(ZSTR_VAL(ncookie.s), ZSTR_LEN(ncookie.s)), ZSTR_LEN(ncookie.s), 0, 0);
+ zend_result result = sapi_add_header_ex(estrndup(ZSTR_VAL(ncookie.s), ZSTR_LEN(ncookie.s)), ZSTR_LEN(ncookie.s), 0, 0);
smart_str_free(&ncookie);
- return SUCCESS;
+ return result;
}
/* }}} */
diff --git a/ext/session/tests/session_start_cookie_header_rejected.phpt b/ext/session/tests/session_start_cookie_header_rejected.phpt
new file mode 100644
index 00000000000..6c3e3b78a3b
--- /dev/null
+++ b/ext/session/tests/session_start_cookie_header_rejected.phpt
@@ -0,0 +1,28 @@
+--TEST--
+session_start() when the SAPI rejects the session cookie header
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+session.gc_probability=0
+--EXTENSIONS--
+session
+--FILE--
+<?php
+
+ob_start();
+
+set_error_handler(function (int $errno, string $errstr): bool {
+ echo "handler: ", $errstr, PHP_EOL;
+ return true;
+});
+
+session_set_cookie_params(['path' => "/\r\nX-Injected: yes"]);
+
+var_dump(session_start());
+var_dump(session_status() === PHP_SESSION_NONE);
+
+?>
+--EXPECT--
+handler: Header may not contain more than a single header, new line detected
+bool(false)
+bool(true)