-
Notifications
You must be signed in to change notification settings - Fork 8k
Description
Description
The GH-17645 seems to be a breaking change in comparison with other PHP versions.
Accessing link: https://hostname/check%2525.php
Earlier php 8.4 version (and older ones):
$_SERVER['HOME'] /var/www/html
$_SERVER['SCRIPT_NAME'] /check%25.php
$_SERVER['REQUEST_URI'] /check%2525.php
$_SERVER['SCRIPT_FILENAME'] /var/www/html/check%25.php
versus php 8.5:
$_SERVER['HOME'] /var/www/html
$_SERVER['SCRIPT_NAME'] /check%25.php
$_SERVER['REQUEST_URI'] /check%2525.php
$_SERVER['SCRIPT_FILENAME'] /var/www/html/check%.php
Now it gets doubledecoded.
Apache seem to handle as expected here:
...>SCRIPT_FILENAMEproxy:fcgi://localhost/var/www/html/check%25.php<...>QUERY_STRING\v\17REQUEST_URI/check%2525.php\v\rSCRIPT_NAME/check%25.php<...
More context:
{sa_family=AF_UNIX}, [112 => 2]) = 5
fcntl(5, F_GETFD) = 0
fcntl(5, F_SETFD, FD_CLOEXEC) = 0
poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}])
times({tms_utime=0, tms_stime=0, tms_cutime=0, tms_cstime=0}) = 3055447099
read(5, "\1\1\0\1\0\10\0\0", 8) = 8
read(5, "\0\1\0\0\0\0\0\0", 8) = 8
read(5, "\1\4\0\1\5\2\0\0", 8) = 8
read(5, "\t\33UNIQUE_IDaMPVIQE5oX3W9vLTiZZjnAAAyS8\22\0HTTP_AUTHORIZATION\5\2HTTPSon\v\rSSL_TLS_SNItest.srv.tld\5\2HTTP2on\6\3H2PUSHoff\7\3H2_PUSHoff\t\0H2_PUSHED\f\0H2_PUSHED_ON\f\1H2_STREAM_ID3\r\fH2_STREAM_TAG642972-180-3\21\1proxy-nokeepalive1\17FHTTP_USER_AGENTMozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0\v?HTTP_ACCEPTtext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\24\16HTTP_ACCEPT_LANGUAGEen-US,en;q=0.5\24\27HTTP_ACCEPT_ENCODINGgzip, deflate, br, zstd\v7HTTP_COOKIE__stripe_mid=896a9b1c-27db-4c99-84c0-7d824b516c1c64d868\36\1HTTP_UPGRADE_INSECURE_REQUESTS1\23\10HTTP_SEC_FETCH_DESTdocument\23\10HTTP_SEC_FETCH_MODEnavigate\23\4HTTP_SEC_FETCH_SITEnone\23\2HTTP_SEC_FETCH_USER?1\r\6HTTP_PRIORITYu=0, i\7\10HTTP_TEtrailers\t\rHTTP_HOSTtest.srv.tld\4<PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\20\0SERVER_SIGNATURE\17\10SERVER_SOFTWAREApache/2\v\rSERVER_NAMEtest.srv.tld\v\16SERVER_ADDRmo.di.fi.ed\v\3SERVER_PORT443\v\vREMOTE_ADDRmo.di.fi.ed\r\rDOCUMENT_ROOT/var/www/html\16\5REQUEST_SCHEMEhttps\16\0CONTEXT_PREFIX\25\rCONTEXT_DOCUMENT_ROOT/var/wwwhtml\f\23SERVER_ADMINwebmaster@localhost\0170SCRIPT_FILENAMEproxy:fcgi://localhost/var/www/html/check%25.php\v\5REMOTE_PORT43258\21\7GATEWAY_INTERFACECGI/1.1\17\10SERVER_PROTOCOLHTTP/2.0\16\3REQUEST_METHODGET\f\0QUERY_STRING\v\17REQUEST_URI/check%2525.php\v\rSCRIPT_NAME/check%25.php", 1282) = 1282
read(5, "\1\4\0\1\0\0\0\0", 8) = 8
newfstatat(AT_FDCWD, "/var/www/html/check%.php", 0x7fffb1edb9c0, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
newfstatat(AT_FDCWD, "/var/www/html", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/var/www", {st_mode=S_IFDIR|0711, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
newfstatat(AT_FDCWD, "", 0x7fffb1edddc0, 0) = -1 ENOENT (No such file or directory)
[..]
According to CGI RFC, the SCRIPT_NAME is not url encoded:
https://datatracker.ietf.org/doc/html/rfc3875#section-4.1.13
And with the SCRIPT_FILENAME that we get the full path - gets url decoded by default with GH-17645 MR.
Apache had similar double decoding issues with their patches in 2.4.60 version, but they've fixed with 2.4.63
https://www.apachelounge.com/changelog-2.4.html
*) mod_proxy_fcgi: Don't re-encode SCRIPT_FILENAME when set via SetHandler.
PR 69203. [Yann Ylavic]
Food for thought:
The setting that brings back the old behavior:
fastcgi.script_path_encoded = on
Shouldn't the setting be the opposite? If the script path is encoded - then use decoding. If it's not url encoded - then decoding is not needed, thus off?
PHP Version
PHP 8.5.0beta2 (cli) (built: Sep 12 2025 11:40:47) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.5.0-dev, Copyright (c) Zend Technologies
with Zend OPcache v8.5.0beta2, Copyright (c), by Zend Technologies
Operating System
Debian 12