Friday, November 3. 2006
In the past PHP has been criticized very often for the possibility to allow URLs in include and require statements. Actually this is not very surprising, because it is the cause for the most dangerous vulnerabilities in PHP applications the often called Remote URL Include vulnerabilities.
Because of this many security researchers recommend disabling the php.ini directive allow_url_fopen in PHP installations. Unfortunately most people recommending this are unaware that this will break lots of applications and is not a 100% solution to stop remote URL includes and therefore INSECURE.
Often users have requested that PHP allows disabling URL support for include and require statements while allowing it for the other filesystem functions. Because of this it was planned to have allow_url_include in PHP 6. After some discussion the feature was backported to the PHP 5.2.0 tree.
Most probably security researchers will now change their recommendations and tell people to disable only allow_url_include.
Unfortunately neither allow_url_fopen nor allow_url_include are a solution for include vulnerabilities. On the one hand it is still dangerous enough to have local file include vulnerabilities in your applications, because quite often it is possible for an attacker to get PHP code into files on the server (sessiondata, fileupload, logfiles,...).
On the other hand allow_url_fopen and allow_url_include only protect against URL handlers marked as URL. This affects http(s) and ftp(s) but it does not affect php or data (new in 5.2.0) URLs. With both URL types it is trivially possible to inject arbitrary PHP code.
Example 1: Use php://input to read the POST data
<?php // Insecure Include
// The following Include statement will
// include and execute everything POSTed
// to the server
include "php://input";
?>
Example 2: Use data: to Include arbitrary code
<?php // Insecure Include
// The following Include statement will
// include and execute the base64 encoded
// payload. Here this is just phpinfo()
include "data:;base64,PD9waHAgcGhwaW5mbygpOz8+";
?>
Taking this into account it should become obvious that neither allow_url_fopen nor allow_url_include are protections. Both are just filters that filter a few attack vectors away. The only 100% solution to remote URL include vulnerabilities is our Suhosin extension.