Сообщения об ошибках
С точки зрения PHP-безопасности вывод ошибок несёт как вред, так и пользу.
Стандартная тактика атаки состоит в профилировании системы: ввод неправильных данных
и анализ содержания и характера сообщений об ошибках. Взломщик получает
информацию о сервере и определяет слабые места. Пример атаки: взломщик получает
информацию о странице после отправки формы, а затем переопределяет или изменяет
передаваемые значения:
Пример #1 Атака на переменные в HTML-странице
<form method="post" action="/?originalUrl=https%3A%2F%2Fwww.php.net%2F%26quot%3Battacktarget%3Fusername%3Dbadfoo%26amp%3Bamp%3Bpassword%3Dbadfoo%26quot%3B%26gt%3B%2520%2520%2520%2520%26lt%3Binput%2520type%3D%26quot%3Bhidden%26quot%3B%2520name%3D%26quot%3Busername%26quot%3B%2520value%3D%26quot%3Bbadfoo%26quot%3B%2520%2F%26gt%3B%2520%2520%2520%2520%26lt%3Binput%2520type%3D%26quot%3Bhidden%26quot%3B%2520name%3D%26quot%3Bpassword%26quot%3B%2520value%3D%26quot%3Bbadfoo%26quot%3B%2520%2F%26gt%3B%26lt%3B%2Fform%26gt%3B%253C%2Fpre">
При отладке сообщения об ошибках в PHP-коде возвращают полезную для разработчика
информацию: показывают функцию, номер строки в файле или PHP-файл, в которых произошёл сбой.
Эта информация помогает злоумышленнику во взломе. PHP-разработчик часто пользуется
функциями show_source(), highlight_string()
и highlight_file() как методами отладки, но на живых сайтах
это раскрывает скрытые переменные, непроверенный синтаксис
и другую опасную информацию. Повышенную опасность несёт запуск
в публичных частях сайта открытого исходного кода со встроенными механизмами и методами отладки.
Злоумышленник попытается взломать страницу методом перебора, или «грубой силы» (англ. brute force),
путём отправки общих строк отладки, если узнает,
какой техникой отладки пользуется разработчик:
Пример #2 Пример стандартных отладочных переменных
<form method="post" action="/?originalUrl=https%3A%2F%2Fwww.php.net%2F%26quot%3Battacktarget%3Ferrors%3DY%26amp%3Bamp%3Bshowerrors%3D1%26amp%3Bamp%3Bdebug%3D1%26quot%3B%26gt%3B%2520%2520%2520%2520%26lt%3Binput%2520type%3D%26quot%3Bhidden%26quot%3B%2520name%3D%26quot%3Berrors%26quot%3B%2520value%3D%26quot%3BY%26quot%3B%2520%2F%26gt%3B%2520%2520%2520%2520%26lt%3Binput%2520type%3D%26quot%3Bhidden%26quot%3B%2520name%3D%26quot%3Bshowerrors%26quot%3B%2520value%3D%26quot%3B1%26quot%3B%2520%2F%26gt%3B%2520%2520%2520%2520%26lt%3Binput%2520type%3D%26quot%3Bhidden%26quot%3B%2520name%3D%26quot%3Bdebug%26quot%3B%2520value%3D%26quot%3B1%26quot%3B%2520%2F%26gt%3B%26lt%3B%2Fform%26gt%3B%253C%2Fpre">
Открытость системы к проверке ошибок
снабжает злоумышленника дополнительной информацией
независимо от метода обработки ошибок.
Сам стиль стандартной информации о PHP-ошибке указывает,
что система работает на PHP. При просмотре
.html-страницы и исследовании бэкенда в поиске слабых мест в системе,
взломщик вводит неверные данные и узнаёт, что систему построили на PHP.
Вывод информации об ошибке, которая возникла в функции, сообщает, работает ли в системе
конкретный движок базы данных, или даёт подсказки, как запрограммировали
или спроектировали веб-страницу. Это помогает злоумышленнику глубже исследовать
открытые порты базы данных или искать конкретные ошибки
и слабые места на веб-странице. Злоумышленник передаёт неверные данные
и по номерам строк с ошибками определяет порядок аутентификации в скрипте, или проверяет,
содержит ли код другие бреши, которые получится использовать в отдельных частях скрипта.
Вывод информации об ошибках в файловой системе или стандартных PHP-ошибок сообщает, с какими
привилегиями запустили веб-сервер, и как организовали каталоги сервера.
Коды ошибок в отладочной информации, которые записал разработчик, усугубляют проблему
и упрощают доступ к информации, которая раньше была «скрыта».
Проблему решают тремя базовыми способами. Первый способ —
тщательно изучить каждую функцию и компенсировать бо́льшую часть ошибок.
Второй — отключить вывод сообщений об ошибках в запущенном коде.
И третий способ — использовать функции, которые устанавливают пользовательский
обработчик PHP-ошибок. Иногда защищаются всеми тремя способами,
в зависимости от политики безопасности, которую принял для себя разработчик.
Способ заранее обнаружить проблему вывода конфиденциальной информации —
изменить уровень сообщений об ошибках в PHP-коде функцией error_reporting(),
которая помогает защитить код и выявить опасные переменные.
На время тестирования кода, перед развёртыванием в рабочей среде,
вывод сообщений об ошибках устанавливают на уровень E_ALL,
с которым быстро находят области, в которых переменные открываются
для «заражения» — подмены или модификации.
С момента готовности кода к развёртыванию требуется вызывать функцию error_reporting()
со значением 0, чтобы отключить вывод сообщений об ошибках,
либо отключить вывод ошибок в файле php.ini — через директиву display_errors,
чтобы изолировать код от проверки. Разработчику потребуется также
определить путь к файлу лога через директиву error_log
и включить директиву log_errors.
Пример #3 Поиск опасных переменных с выводом ошибок уровня E_ALL
<?php
if ($username) { // Переменную $username не инициализировали — не установили начальное значение — и не проверили
$good_login = 1;
}
if ($good_login == 1) { // Переменная $good_login не проинициализируется, а проверка не пройдёт,
// если предыдущая проверка провалится
readfile ("/highly/sensitive/data/index.html");
}
?>