summaryrefslogtreecommitdiffstats
path: root/php-cve-2026-6735.patch
blob: ba1dbb0d5d9dc1e406d02a84ccae168a1a8ee66f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
From 3322601b31ccedeb13a3203bbe5fd7b6cb4679a9 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Tue, 19 May 2026 09:47:08 +0200
Subject: [PATCH 5/5] GHSA-7qg2-v9fj-4mwv: [fpm] XSS within status endpoint

Fixes GHSA-7qg2-v9fj-4mwv
Fixes CVE-2026-6735

(cherry picked from commit 99a5ad7441de9914246c7863adb6997396008b9d)
(cherry picked from commit 943de7efee24c0e7d826a3469d3b35b4ad0f4193)
---
 NEWS                                          |  4 ++
 sapi/fpm/fpm/fpm_status.c                     | 20 ++++--
 .../tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt | 62 +++++++++++++++++++
 3 files changed, 82 insertions(+), 4 deletions(-)
 create mode 100644 sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt

diff --git a/NEWS b/NEWS
index b46e2b0c5d..d8ae595068 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,10 @@ PHP                                                                        NEWS
 
 Backported from 8.2.31
 
+- FPM:
+  . Fixed GHSA-7qg2-v9fj-4mwv (XSS within status endpoint). (CVE-2026-6735)
+    (Jakub Zelenka)
+
 - SOAP:
   . Fixed GHSA-m33r-qmcv-p97q (Use-after-free after header parsing failure with
     SOAP_PERSISTENCE_SESSION). (CVE-2026-7261) (ilutov)
diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c
index a2ee398d29..d9a8263089 100644
--- a/sapi/fpm/fpm/fpm_status.c
+++ b/sapi/fpm/fpm/fpm_status.c
@@ -384,8 +384,8 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
 		/* no need to test the var 'full' */
 		if (full_syntax) {
 			int i, first;
-			size_t len;
-			char *query_string;
+			size_t len, len_uri;
+			char *query_string, *request_uri_string;
 			struct timeval duration, now;
 #ifdef HAVE_FPM_LQ
 			float cpu;
@@ -412,13 +412,22 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
 					}
 				}
 
+				request_uri_string = NULL;
+				len_uri = 0;
+				if (proc.request_uri[0] != '\0') {
+					if (!encode) {
+						request_uri_string = proc.request_uri;
+					} else {
+						request_uri_string = php_escape_html_entities_ex((unsigned char *)proc.request_uri, strlen(proc.request_uri), &len_uri, 1, ENT_DISALLOWED | ENT_HTML_DOC_XML1 | ENT_COMPAT, NULL, 1 TSRMLS_CC);
+					}
+				}
 				query_string = NULL;
 				len = 0;
 				if (proc.query_string[0] != '\0') {
 					if (!encode) {
 						query_string = proc.query_string;
 					} else {
-						query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), &len, 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, 1 TSRMLS_CC);
+						query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), &len, 1, ENT_DISALLOWED | ENT_HTML_DOC_XML1 | ENT_COMPAT, NULL, 1 TSRMLS_CC);
 					}
 				}
 
@@ -445,7 +454,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
 					proc.requests,
 					duration.tv_sec * 1000000UL + duration.tv_usec,
 					proc.request_method[0] != '\0' ? proc.request_method : "-",
-					proc.request_uri[0] != '\0' ? proc.request_uri : "-",
+					request_uri_string ? request_uri_string: "-",
 					query_string ? "?" : "",
 					query_string ? query_string : "",
 					proc.content_length,
@@ -461,6 +470,9 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */
 				if (len > 0 && query_string) {
 					efree(query_string);
 				}
+				if (len_uri > 0 && request_uri_string) {
+					efree(request_uri_string);
+				}
 			}
 
 			if (full_post) {
diff --git a/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt b/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt
new file mode 100644
index 0000000000..55827b1bc8
--- /dev/null
+++ b/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt
@@ -0,0 +1,62 @@
+--TEST--
+FPM: Test status page
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+include "include.inc";
+
+$logfile = dirname(__FILE__).'/php-fpm.log.tmp';
+$port = 9000+PHP_INT_SIZE;
+
+$cfg = <<<EOT
+[global]
+error_log = $logfile
+[unconfined]
+listen = 127.0.0.1:$port
+pm.status_path = /status
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 2
+pm.min_spare_servers = 2
+pm.max_spare_servers = 3
+EOT;
+
+$fpm = run_fpm($cfg, $tail);
+if (is_resource($fpm)) {
+    fpm_display_log($tail, 2);
+    try {
+
+		$html = run_request('127.0.0.1', $port, '/<script>alert(1)</script>', '<script>alert(2)</script>');
+
+		$html = run_request('127.0.0.1', $port, '/status', 'full&html');
+		var_dump(strpos($html, 'text/html') && strpos($html, 'DOCTYPE') && strpos($html, 'PHP-FPM Status Page'));
+		var_dump(strpos($html, 'alert(1)') && strpos($html, 'alert(2)'));
+		var_dump(strpos($html, '<script>'));
+		//var_dump($html);
+
+		echo "IPv4 ok\n";
+	} catch (Exception $e) {
+		echo "IPv4 error\n";
+	}
+
+	proc_terminate($fpm);
+    stream_get_contents($tail);
+    fclose($tail);
+    proc_close($fpm);
+}
+
+?>
+--EXPECTF--
+[%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
+[%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
+bool(true)
+bool(true)
+bool(false)
+IPv4 ok
+--CLEAN--
+<?php
+    $logfile = dirname(__FILE__).'/php-fpm.log.tmp';
+    @unlink($logfile);
+?>
-- 
2.54.0

From 630b48523b5a0de368138c421bd3dbae6b0552a0 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Tue, 19 May 2026 11:25:29 +0200
Subject: [PATCH] relax test (may fail when script not in status page)

(cherry picked from commit 31ed74945eb92e073b51bd8ca114a123c9c20990)
---
 sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt b/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt
index 55827b1bc8..674b4ddcb3 100644
--- a/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt
+++ b/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt
@@ -32,9 +32,11 @@ if (is_resource($fpm)) {
 
 		$html = run_request('127.0.0.1', $port, '/status', 'full&html');
 		var_dump(strpos($html, 'text/html') && strpos($html, 'DOCTYPE') && strpos($html, 'PHP-FPM Status Page'));
-		var_dump(strpos($html, 'alert(1)') && strpos($html, 'alert(2)'));
-		var_dump(strpos($html, '<script>'));
-		//var_dump($html);
+
+		// output only if script present but not escaped
+		if (strpos($html, 'alert') && strpos($html, '<script>')) {
+			var_dump($html);
+		}
 
 		echo "IPv4 ok\n";
 	} catch (Exception $e) {
@@ -52,8 +54,6 @@ if (is_resource($fpm)) {
 [%d-%s-%d %d:%d:%d] NOTICE: fpm is running, pid %d
 [%d-%s-%d %d:%d:%d] NOTICE: ready to handle connections
 bool(true)
-bool(true)
-bool(false)
 IPv4 ok
 --CLEAN--
 <?php
-- 
2.54.0

From 4abe506a9863ec2f236689fc6b64549cc2fcb260 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Tue, 19 May 2026 11:40:42 +0200
Subject: [PATCH 2/2] fix test name

(cherry picked from commit 16802565461621322e97ba7ac22e2699885ed73a)
---
 sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt b/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt
index 674b4ddcb3..912237c5e2 100644
--- a/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt
+++ b/sapi/fpm/tests/ghsa-7qg2-v9fj-4mwv-status-xss.phpt
@@ -1,5 +1,5 @@
 --TEST--
-FPM: Test status page
+FPM: GHSA-7qg2-v9fj-4mwv - status xss
 --SKIPIF--
 <?php include "skipif.inc"; ?>
 --FILE--
-- 
2.54.0