Commit 6393bde658d for php
commit 6393bde658d1041ed0b7e9534d0a857fe773669e
Author: Jorg Sowa <jorg.sowa@gmail.com>
Date: Sun Nov 15 00:03:09 2026 +0100
ext/session: prevent creation of fixed sid in php_session_rfc1867 (GH-22113)
Closes GH-22113
diff --git a/NEWS b/NEWS
index a5fa9c4ead9..64c61f8f121 100644
--- a/NEWS
+++ b/NEWS
@@ -104,6 +104,10 @@ PHP NEWS
. Fix trampoline leak when object construction fails for lazy object.
(ndossche)
+- Session:
+ . Fixed session upload progress to respect session.use_only_cookies.
+ (jorgsowa)
+
- Standard:
. Fixed dns_get_record() returning partially built records for malformed
DNS responses. (Marti2203)
diff --git a/ext/session/session.c b/ext/session/session.c
index 63072b331dd..fc4f201a63d 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -1708,8 +1708,8 @@ PHPAPI zend_result php_session_start(void) /* {{{ */
* Cookies are preferred, because initially cookie and get
* variables will be available.
* URL/POST session ID may be used when use_only_cookies=Off.
- * session.use_strice_mode=On prevents session adoption.
- * Session based file upload progress uses non-cookie ID.
+ * session.use_strict_mode=On prevents session adoption.
+ * Session based file upload progress respects use_only_cookies.
*/
if (!PS(id)) {
@@ -3316,7 +3316,7 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_
if (data->name && data->value && value_len) {
size_t name_len = strlen(data->name);
- if (name_len == progress->sname_len && memcmp(data->name, PS(session_name), name_len) == 0) {
+ if (!PS(use_only_cookies) && name_len == progress->sname_len && memcmp(data->name, PS(session_name), name_len) == 0) {
zval_ptr_dtor(&progress->sid);
ZVAL_STRINGL(&progress->sid, (*data->value), value_len);
} else if (name_len == strlen(PS(rfc1867_name)) && memcmp(data->name, PS(rfc1867_name), name_len + 1) == 0) {
diff --git a/ext/session/tests/rfc1867_sid_post_use_only_cookies.phpt b/ext/session/tests/rfc1867_sid_post_use_only_cookies.phpt
new file mode 100644
index 00000000000..8a22b261369
--- /dev/null
+++ b/ext/session/tests/rfc1867_sid_post_use_only_cookies.phpt
@@ -0,0 +1,34 @@
+--TEST--
+session rfc1867 upload progress ignores session ID from POST data with default session.use_only_cookies
+--INI--
+upload_max_filesize=1024
+session.upload_progress.cleanup=0
+session.upload_progress.freq=0
+--EXTENSIONS--
+session
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--POST_RAW--
+Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737
+-----------------------------20896060251896012921717172737
+Content-Disposition: form-data; name="PHPSESSID"
+
+rfc1867-sid-post-use-only-cookies
+-----------------------------20896060251896012921717172737
+Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
+
+rfc1867_sid_post_use_only_cookies.php
+-----------------------------20896060251896012921717172737
+Content-Disposition: form-data; name="file1"; filename="file1.txt"
+
+1
+-----------------------------20896060251896012921717172737--
+--FILE--
+<?php
+session_id("rfc1867-sid-post-use-only-cookies");
+session_start();
+var_dump(isset($_SESSION["upload_progress_" . basename(__FILE__)]));
+session_destroy();
+?>
+--EXPECT--
+bool(false)
diff --git a/tests/basic/oom_rfc1867_upload_progress.phpt b/tests/basic/oom_rfc1867_upload_progress.phpt
index 77512e33719..5a8fd614c02 100644
--- a/tests/basic/oom_rfc1867_upload_progress.phpt
+++ b/tests/basic/oom_rfc1867_upload_progress.phpt
@@ -22,12 +22,12 @@
'session.upload_progress.min_freq=0',
];
-/* The progress handler only engages once it has seen both the session id and
- * the progress key, so those two parts come first. */
+/* php-cgi inherits $_ENV; the progress handler takes the session id from the cookie. */
+$_ENV['HTTP_COOKIE'] = 'PHPSESSID=abcdef0123456789abcdef0123456789';
+
+/* The progress handler only engages once it has seen the progress key, so that part comes first. */
function oom_rfc1867_progress_preamble($fh): void
{
- oom_rfc1867_part($fh, 'Content-Disposition: form-data; name="PHPSESSID"',
- 'abcdef0123456789abcdef0123456789');
oom_rfc1867_part($fh, 'Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"', 'k');
}
@@ -73,8 +73,6 @@ function oom_rfc1867_progress_preamble($fh): void
* progress key on MULTIPART_EVENT_FORMDATA, so the soft limit is reached
* inside the handler rather than in the parser. */
oom_rfc1867_request(function ($fh) {
- oom_rfc1867_part($fh, 'Content-Disposition: form-data; name="PHPSESSID"',
- 'abcdef0123456789abcdef0123456789');
fwrite($fh, '--' . OOM_RFC1867_BOUNDARY . "\r\n"
. "Content-Disposition: form-data; name=\"PHP_SESSION_UPLOAD_PROGRESS\"\r\n\r\n");
oom_rfc1867_fill($fh, 1024 * 1024);