Рубрика:
Безопасность /
Безопасность
|
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|
СЕРГЕЙ ЯРЕМЧУК, фрилансер. Автор более 800 статей и шести книг. С «СА» с первого номера. Интересы: сетевые технологии, защита информации, свободные ОС
Защищаем PHP-приложения с помощью Suhosin
Сегодня PHP – один из самых популярных языков, используемых при разработке веб-приложений. Простота в изучении и использовании привлекает к нему новичков.
Принято считать, что ошибки при программировании свойственны только новичкам, которые многого еще не умеют и не знают, но это не так. Программист с опытом способен избежать большинства проблем, но в то же время он также не застрахован от ошибок. Кроме того, многие сайты сегодня делаются под заказ специалистами-аутсорсерами и не всегда исполнитель может, умеет и хочет провести полноценный аудит собственного кода. Крупные проекты также содержат ошибки. Результат – сегодня только и слышно о PHP Include, SQL Injection, Cross site scripting (XSS) и других атаках, направленных на веб-сервисы. Несмотря на то что об этих технологиях и методах защиты рассказано многое, взломы все равно продолжаются.
Так, по статистике Web Application Security Consortium [1] количество взломов веб-серверов в 2005 году по сравнению с 2004 годом увеличилось в три раза. Это, конечно, не самая точная и полная статистика, зато в ней фигурируют только крупные проекты, защитой которых занимаются отнюдь не новички. Среди основных причин такой негативной тенденции называют широкую доступность инструментов, необходимых для проведения атаки, и недостаточное внимание со стороны разработчиков сайтов к вопросам безопасности.
Выходов из этой ситуации может быть несколько. Это и аудит кода, заказанный у сторонней организации, автоматическое тестирование с помощью специализированных сканеров безопасности, работающих на прикладном уровне, вроде Acunetix Web Vulnerability Scanner [2] и правильная настройка всех компонентов системы (веб-сервера, параметров PHP и базы данных). Ручная проверка больших объемов кода является сложной и трудоемкой задачей, требующей больших знаний в различных областях, займет много времени и 100% гарантии все равно не даст. Сканеры безопасности, как правило, позволяют выявить лишь общие ошибки. Вероятно, поэтому в последнее время активно развиваются проекты, позволяющие защититься от атак глобально, независимо от присутствия ошибок на сайте. Один из вариантов – защита сервиса с помощью файервола веб-приложений [3], разработчики Suhosin пошли несколько иным путем.
Проекты Hardening-Patch и Suhosin
Это два проекта от одного разработчика, имеющие сходную задачу, только реализованы по-разному. Задача – защита серверов и пользователей от целого ряда известных проблем в приложениях и ядре PHP. Кроме того, с помощью Hardening-Patch или Suhosin можно защититься от неизвестных уязвимостей. При этом Hardening-Patch реализован в виде патча к PHP и может быть использован только после полной пересборки PHP. В Suhosin входят две независимые части, которые могут использоваться как раздельно, так и в совместно.
Первая часть – небольшой патч к ядру, осуществляющий низкоуровневую защиту структур данных Zend LinkedList и HashMap против переполнения буфера и других уязвимостей ядра PHP. Это реализуется посредством хранения реальных указателей на используемые деструкторы, и каждый раз при его вызове происходит проверка списка. Патч защищает ядро и модули PHP от уязвимости форматной строки и от ошибок в реализации функции realpath, присущей некоторым платформам (приводя ее к принятой в FreeBSD).
Вторая часть реализована в виде расширения, которое фактически и осуществляет всю основную защиту, при необходимости его очень просто доустановить в уже рабочую систему, без полной пересборки PHP. Здесь возможности уже гораздо шире (полный список приведен на сайте проекта http://www.hardened-php.net/suhosin/a_feature_list.html):
- добавлены функции sha256(), sha256_file() и поддержка blowfish для всех платформ;
- кодирование Cookies и данных сессии;
- запрещение вставки URL, закачки файлов и доступа к произвольным файлам, верификация загруженных файлов через внешний скрипт, запрет загрузки исполняемых файлов, удаление двоичных данных из загружаемого файла;
- отключение функции eval(), запуск приложений с использованием eval() с применением белого и черного списков;
- принудительная установка максимальной глубины рекурсии;
- поддержка виртуальных узлов и каталогов, настраиваемых через черный и белый списки;
- защита от прерывания HTTP-заголовка (HTTP Response Splitting);
- защита глобальных переменных от extract и import_request_vars, а также от скриптов, манипулирующих memory_limit;
- защита от длинных и неправильных идентификаторов сессии;
- фильтрование ASCII-символов;
- игнорирование переменных GET, POST, COOKIE с целым рядом параметров;
- установка лимитов ряду переменных REQUEST.
В случае нарушения установленных правил возможна блокировка переменных, отсылка определенного HTTP-кода ответа, перенаправление браузера пользователя, выполнение другого PHP-скрипта. Все события заносятся в журналы, для чего может использоваться syslog, свой модуль или внешний скрипт. В журнале появится запись об IP-адресе атакующего, а также файл и номер строки, которые были использованы для атаки.
Версии Hardening-Patch и Suhosin-Patch привязаны к соответствующей версии PHP, последние версии расширения Suhosin совместимы практически со всеми версиями PHP. Судя по ответу в FAQ, размещенному на сайте, Suhosin сейчас продвигается на замену Hardening-Patch, поэтому его и рекомендуется использовать. Распространяются эти два проекта под PHP License, version 3.01.
Установка Suhosin
Установка Suhosin состоит из двух этапов: наложение патча на PHP с последующей его пересборкой и компиляция модуля расширения. Хотя возможна и сборка со встроенным расширением.
В репозитарии Ubuntu 6.06 на момент написания статьи была доступна версия php 5.12, для которой не имеется патча Suhosin. Поэтому будем устанавливать из исходных текстов. Скачиваем PHP, патч suhosin под используемую версию PHP и расширение. Все это распаковываем, накладываем патч и компилируем.
$ tar -xvjf php-5.1.6.tar.bz2
$ gunzip suhosin-patch-5.1.6-0.9.5.patch.gz
$ cd php-5.1.6
$ patch -p 1 -i ../suhosin-patch-5.1.6-0.9.5.patch
$ make
$ make test
$ sudo make install
Хотя, чтобы не было проблем с зависимостями, в Ubuntu перед конфигурированием рекомендуется дать команду:
$ sudo apt-get build-dep php5
и установить все недостающие пакеты (хотя большая их часть в конкретном случае явно лишняя). Минимальный набор для Ubuntu устанавливается так:
$ sudo apt-get install bison flex libxml2 libxml2-dev
После этих операций PHP должен работать корректно и без ошибок. Если планируется, скомпилировать расширение вместе с PHP, то распаковываем архив suhosin-0.9.5.tgz и копируем все файлы из каталога src в ext/suhosin.
Далее обычная сборка php, при конфигурировании не забываем включить опцию --enable-suhosin. Собираем модуль расширения:
$ cd suhosin-0.9.5
$ phpize
Configuring for:
PHP Api Version: 20041225
Zend Module Api No: 20050922
Zend Extension Api No: 220051025
$ ./configure
|
По умолчанию скомпилированный модуль будет установлен в каталог, в котором он компилируется, что не очень удобно. Поэтому лучше использовать директиву --prefix=/usr/lib.
$ make
$ sudo make install
Настройка Suhosin
Все настройки Suhosin производятся в файле php.ini. Следует учесть, что патч поддерживает только опции регистрации. Первая запись, которая должна быть обязательно помещена в файл, – это подключение модуля suhosin.so (сам модуль должен быть виден переменной LD_RUN_PATH):
extension=suhosin.so
В таблице 1 приведены основные опции Suhosin. После установки Suhosin будет работать с настройками по умолчанию, которые показаны во втором столбце таблицы. Константы могут использоваться только совместно с Suhosin-патчем, иначе придется работать с их числовыми аналогами, для некоторых значений они приведены в скобках. Остальные вы найдете в документации проекта.
Таблица 1. Опции Suhosin
Опция
|
Значение по умолчанию
|
Возможные значения
|
Пояснение
|
Опции протоколирования
|
suhosin.log.syslog
|
S_ALL (511)
|
S_MEMORY, S_MISC, S_VARS, S_FILES, S_INCLUDE, S_SQL, S_EXECUTOR, S_MAIL, S_SESSION, S_ALL
|
Указывает, какие классы тревог регистрируются в syslog. Вне зависимости от настроек S_MEMORY регистрируется всегда
|
suhosin.log.syslog.facility
|
LOG_USER (9)
|
LOG_KERN, LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, LOG_SYSLOG, LOG_LPR, LOG_NEWS, LOG_UUCP, LOG_CRON, LOG_AUTHPRIV, LOG_LOCAL0 ... LOG_LOCAL7
|
Указывает на компонент, который будет заносить сообщения в syslog
|
suhosin.log.syslog.priority
|
LOG_ALERT (1)
|
LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG, LOG_ERR
|
Приоритет сообщения
|
suhosin.log.sapi
|
S_ALL
|
–
|
Определяет, какие классы тревог регистрируются через SAPI
|
|
0
|
–
|
Какие классы тревог будут регистрироваться через внешний скрипт, S_MEMORY не может регистрироваться, так как его появление означает, что процесс, возможно, в нестабильном состоянии
|
|
–
|
–
|
Какие классы тревог будут регистрироваться через PHP-скрипт, S_MEMORY также не может регистрироваться
|
|
–
|
–
|
Полный путь к внешнему скрипту. Скрипту будет передано два параметра. Первый – класс тревоги в буквенной нотации, второй – сообщение
|
|
–
|
–
|
Полный путь к внешнему php-скрипту. Ему будет передано два параметра: SUHOSIN_ERRORCLASS и SUHOSIN_ERROR, назначение которых аналогично предыдущему
|
suhosin.log.use-x-forwarded-for
|
0 (отключено)
|
–
|
Обычно IP-адрес атакующего извлекается из переменной REMOTE_ADDR, включение этой опции позволит использовать HTTP-заголовок X-Forwarded-For (например, используется прокси)
|
Опции исполнения
|
suhosin.executor.max_depth
|
0 (отключено)
|
–
|
Задает максимально разрешенную глубину стека, после чего выполнение скрипта будет остановлено
|
suhosin.executor.include.max_traversal
|
0
|
–
|
Определяет, сколько знаков ../ в запросе будет расценено как атака
|
suhosin.executor.include.whitelist
|
–
|
–
|
Разделенный запятой список разрешенных или запрещенных URL, которые можно включить в скрипт. Если не указан белый список, используется только черный, если не указаны оба, то вставка URL запрещена
|
suhosin.executor.include.blacklist
|
–
|
–
|
|
suhosin.executor.func.whitelist
|
–
|
–
|
Список разрешенных или запрещенных для вызова функций. Если белый список пуст, анализируется черный, если пусты оба, то функции запрещены
|
suhosin.executor.func.blacklist
|
|
–
|
|
suhosin.executor.eval.whitelist
|
–
|
–
|
Список функций, разделенных запятой, которые разрешено или запрещено запускать посредством eval(). Если белый список пуст, анализируется черный, если пусты оба, то вызов функции через eval() запрещено
|
suhosin.executor.eval.blacklist
|
–
|
–
|
|
suhosin.executor.disable_eval
|
0
|
–
|
Глобальное отключение использования eval(). В журнале будут отображены все нарушения этого правила, поэтому можно отследить все случаи использования eval()
|
suhosin.executor.disable_emodifier
|
0
|
–
|
Модификатор /e внутри функции preg_replace() позволяет выполнять код, разработчики рекомендуют отключить ее использование и применять preg_replace_callback()
|
Дополнительные опции
|
suhosin.simulation
|
0
|
–
|
Очень полезная опция, позволяет переводить систему в режим регистрации нарушений, то есть создав правила, вы можете некоторое время только регистрировать нарушения, чтобы затем комплексно оценить работу скриптов
|
suhosin.mail.protect
|
0
|
0, 1, 2
|
Включает защиту функции mail(). 0 – отключена, 1 – контроль Subject:, To:, 2 – дополнительно To:, CC:, BCC:
|
suhosin.memory_limit
|
0
|
–
|
Управление изменением memory_limit, при 0 – изменение запрещено, любое число показывает предел в Мб, при запросе скриптом большего значения его выполнение будет остановлено
|
Опции прозрачного шифрования
|
suhosin.session.encrypt
|
1 (включено)
|
–
|
Разрешение/отключение шифрования сессии
|
suhosin.session.cryptkey
|
–
|
–
|
Ключ для шифрования сессии
|
suhosin.session.cryptua
|
1
|
|
Зависимость ключа шифрования от полей User-Agent, Documentroot
|
suhosin.session.cryptdocroot
|
–
|
–
|
|
suhosin.session.cryptraddr
|
0
|
0-4
|
Число октетов REMOTE_ADDR, от которых будет зависить ключ шифрования
|
suhosin.cookie.encrypt
|
1
|
–
|
Шифрование Cookie. Значение остальных опций suhosin.cookie.cryptkey, suhosin.cookie.cryptua, suhosin.cookie.cryptdocroot, suhosin.cookie.cryptraddr аналогично
|
Опции фильтрации
|
suhosin.filter.action
|
–
|
–
|
|
suhosin.cookie.max_array_depth
|
100
|
–
|
Максимальная глубина массива, зарегистрированного через cookie
|
suhosin.cookie.max_array_index_length
|
64
|
–
|
Определяет максимальную длину индексов массива переменных, зарегистрированных через cookie
|
suhosin.cookie.max_name_length
|
64
|
–
|
Определяет максимальную длину имени переменных, зарегистрированных через cookie. Для массивов это имя перед индексом
|
suhosin.cookie.max_totalname_length
|
256
|
–
|
Определяет максимальную длину полного имени переменных, зарегистрированных через cookie
|
suhosin.cookie.max_value_length
|
10000
|
–
|
Определяет максимальную длину переменной, зарегистрированную через cookie
|
suhosin.cookie.max_vars
|
100
|
–
|
Определяет максимальное количество переменных, зарегистрированных через cookie
|
suhosin.cookie.disallow_nul
|
1
|
–
|
Если 1, то символы ASCIIZ в переменных не разрешены
|
suhosin.get.max_array_depth
|
50
|
–
|
Максимальная глубина массива, зарегистрированного через URL Значение остальных опций (suhosin.get.max_array_index_length, suhosin.get.max_name_length, suhosin.get.max_totalname_length, suhosin.get.max_value_length, suhosin.get.max_vars, suhosin.get.disallow_nul) сопоставимы с предыдущими
|
suhosin.post.max_array_depth
|
100
|
–
|
Максимальная глубина массива, зарегистрированного через POST. Значение остальных опций (suhosin.post.max_array_index_length, suhosin.post.max_name_length, suhosin.post.max_totalname_length, suhosin.post.max_value_length, suhosin.post.max_vars, suhosin.post.disallow_nul) сопоставимы с предыдущими
|
suhosin.request.max_array_depth
|
100
|
–
|
Максимальная глубина массива, зарегистрированного через все доступные методы URL, GET , POST или COOKIE. Может быть индивидуально переопределена предыдущими опциями. Также доступны параметры suhosin.request.max_array_index_length, suhosin.request.max_totalname_length, suhosin.request.max_value_length, suhosin.request.max_vars, suhosin.request.max_varname_length, suhosin.request.disallow_nul
|
suhosin.upload.max_uploads
|
25
|
–
|
Максимальное число файлов, пересылаемых одним запросом
|
suhosin.upload.disallow_elf
|
1
|
–
|
Установка запрета на загрузку ELF-файлов
|
suhosin.upload.disallow_binary
|
0
|
–
|
Установка запрета на загрузку двоичных файлов
|
suhosin.upload.remove_binary
|
0
|
–
|
Установка удаления двоичного контента из загружаемых файлов
|
|
–
|
–
|
Путь к скрипту, который проверяет загружаемый файл. В качестве параметра он получит имя файла, для продолжения загрузки скрипт должен вывести 1 в stdout
|
suhosin.session.max_id_length
|
128
|
–
|
Максимальная длина идентификатора сессии, в случае превышения указанного значения будет создан новый идентификатор
|
На сайте проекта приведен тест производительности, замеренный с помощью скрипта bench.php [6]. При этом использовался компьютер с процессором Pentium 4 с частотой 2,80 Ггц и оперативной памятью 512 Мб. Замеры показали, что система, использующая патч и модуль Suhosin на 8,84 % работает медленнее. На компьютере с процессором 2 Ггц получилась приблизительно такая же цифра. Большую часть ресурсов забирает патч, модуль несильно нагружает систему. Но bench.php использует рекурсивную функцию с большим количеством вызовов, что в рабочих скриптах практически не встречается. Поэтому в реальной системе присутствие Suhosin будет незаметно.
Suhosin является довольно интересным решением, позволяющим защитить веб-сервис, использующий PHP, от большинства известных и неизвестных угроз. В отличие от mod_security, где администратор должен постоянно отслеживать события и подправлять при необходимости правила. В Suhosin достаточно лишь оптимально установить параметры и в дальнейшем система не потребует вмешательства.
- Web Hacking Statistics – http://www.webappsec.org/projects/whid/statistics.shtml.
- Яремчук С. Определяем уязвимость веб-сервиса с помощью Acunetix Web Vulnerability Scanner. //Системный администратор, № 9, 2005 г. – C. 68-69.
- Яремчук С. Как повысить безопасность веб-приложений. //Системный администратор, № 2, 2006 г. – C. 60-66.
- Сайт проекта Hardening-Patch – http://www.hardened-php.net/hphp.
- Сайт проекта Suhosin – http://www.hardened-php.net/suhosin.
- Скрипт bench.php – http://cvs.php.net/viewvc.cgi/ZendEngine2/bench.php?content-type=text/plain&view=co.
- Документация по настройке Hardening-Patch (опции в большинстве схожи с Suhosin) – http://www.hardened-php.net/hardening-patch-0.4.3-manual-alpha.pdf.
Facebook
Мой мир
Вконтакте
Одноклассники
Google+
|