cgi.force_redirect configuration is bypassable due to the environment variable collision

Inhalt

Summary

According to , the configuration directive cgi.force_redirect prevents anyone from calling PHP directly with a URL like http://host.example/cgi-bin/php/secretdir/script.php.
The default value of cgi.force_redirect is 1.

But there is a bug that can cause attackers to bypass restrictions and access php-cgi directly.

Details

Both REDIRECT_STATUS or HTTP_REDIRECT_STATUS are considered legal environment variable while cgi.force_redirect is turned on:

https://github.com/php/php-src/blob/master/sapi/cgi/cgi_main.c#L1905

	/* check force_cgi after startup, so we have proper output */
	if (cgi && CGIG(force_redirect)) {
		/* Apache will generate REDIRECT_STATUS,
		 * Netscape and redirect.so will generate HTTP_REDIRECT_STATUS.
		 * redirect.so and installation instructions available from
		 * http://www.koehntopp.de/php.
		 *   -- kk@netuse.de
		 */
		if (!getenv("REDIRECT_STATUS") &&
			!getenv ("HTTP_REDIRECT_STATUS") &&
			/* this is to allow a different env var to be configured
			 * in case some server does something different than above */
			(!CGIG(redirect_status_env) || !getenv(CGIG(redirect_status_env)))
		) {
			zend_try {
				SG(sapi_headers).http_response_code = 400;
				PUTS(" Security Alert! The PHP CGI cannot be accessed directly.\n\n\ This PHP CGI binary was compiled with force-cgi-redirect enabled.  This\n\
means that a page will only be served up if the REDIRECT_STATUS CGI variable is\n\
set, e.g. via an Apache Action directive. \n\ For more information as to why this behaviour exists, see the \
manual page for CGI security . \n\ For more information about changing this behaviour or re-enabling this webserver,\n\
consult the installation file that came with this distribution, or visit \n\ the manual page . \n");
			} zend_catch {
			} zend_end_try();
#if defined(ZTS) && !defined(PHP_DEBUG)
			/* XXX we're crashing here in msvc6 debug builds at
			 * php_message_handler_for_zend:839 because
			 * SG(request_info).path_translated is an invalid pointer.
			 * It still happens even though I set it to null, so something
			 * weird is going on.
			 */
			tsrm_shutdown();
#endif
			free(bindpath);
			return FAILURE;
		}
	}

Unexpectedly, Redirect-Status header is converted to the HTTP_REDIRECT_STATUS environment variable, allowing the attacker to bypass the cgi.force_redirect variable through HTTP headers.

Impact

The cgi.force_redirect configuration can be bypassed.

While this does not pose significant security risks in most common configurations, certain configurations that modifies the SCRIPT_FILENAME environment variable may allow the arbitrary file inclusion.

Verknuepfte CVEs

CVE-ID Severity (CVE.org) CVSS (CVE.org) EPSS EPSS-% Veroeffentlicht (CVE.org)

CVE-2024-8927

- - - -

Quellen-Details

Bezeichnung Name Kategorie Tags Zielgruppe Sprache Feed-URL
PHP Security (php/php-src GHSA)

php_sec

vendor_advisory php, runtime - de https://github.com/php/php-src/security/advisories