Summary
According to https://www.php.net/manual/en/security.cgi-bin.force-redirect.php, 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("<b>Security Alert!</b> The PHP CGI cannot be accessed directly.\n\n\
<p>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.</p>\n\
<p>For more information as to <i>why</i> this behaviour exists, see the <a href=\"http://php.net/security.cgi-bin\">\
manual page for CGI security</a>.</p>\n\
<p>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\
<a href=\"http://php.net/install.windows\">the manual page</a>.</p>\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.
Summary
According to https://www.php.net/manual/en/security.cgi-bin.force-redirect.php, the configuration directive
cgi.force_redirect
prevents anyone from calling PHP directly with a URL likehttp://host.example/cgi-bin/php/secretdir/script.php
.The default value of
cgi.force_redirect
is1
.But there is a bug that can cause attackers to bypass restrictions and access php-cgi directly.
Details
Both
REDIRECT_STATUS
orHTTP_REDIRECT_STATUS
are considered legal environment variable whilecgi.force_redirect
is turned on:https://github.com/php/php-src/blob/master/sapi/cgi/cgi_main.c#L1905
Unexpectedly,
Redirect-Status
header is converted to theHTTP_REDIRECT_STATUS
environment variable, allowing the attacker to bypass thecgi.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.