Ключевые слова:php, security, apache, mod_php, mysql, chroot, (найти похожие документы)
From: securitylab.ru <http://www.securitylab.ru>
Newsgroups: securitylab.ru
Date: Mon, 14 Aug 2003 14:31:37 +0000 (UTC)
Subject: Основные шаги в защите PHP
Оригинал: http://www.securitylab.ru/?ID=39645
Защищаем PHP. Шаг за шагом.
В предыдущей статье "Защищаем Apache" (http://www.securitylab.ru/?ID=38966)
автор описал метод защиты Web сервера Apache от несанкционированного
доступа из Internet. Благодаря этому методу можно было достичь высокого
уровня защиты, но в случае обслуживания только статических HTML страниц.
Но как же осуществить защиту, когда необходимо взаимодействие с
пользователем, а данные пользователей должны быть сохранены в
локальной базе данных?
Эта статья рассказывает об основных шагах в защите PHP, одном из
наиболее популярных языков создания сценариев, созданном в основном
для создания динамических web-страниц. Для избежания повтора
информации, охваченной в предыдущей статье, мы покажем только основные
различия, от процесса защиты Web сервера Apache.
Операционная система
Как и в предыдущей статье, операционной системой является - FreeBSD
4.7. Однако, представленные методы можно также применять и на более
современных unix и unix-подобных системах. Мы также предполагаем, что
база данных MySQL установлена на хосте, и помещена в каталог
"/usr/local/mysql".
Функциональные возможности
Функциональные возможности будут подобны описанным в предыдущей
статье. Однако, существуют некоторые изменения:
* Web-сервер должен обрабатывать язык PHP
* PHP компонент должен иметь возможность считывать и записывать
пользовательские данные в локально установленной базе данных MySQL
Предложения по защите
Должно быть добавлено следующее:
* PHP конфигурация должна пользоваться преимуществом встроенных
механизмов защиты
* PHP сценарии должены быть выполнены в chrooted среде
* Apache сервер должен отклонять все запросы (GET и POST), которые
содержат HTML-тэги (возможная атака межсайтового
скриптинга), знаки апострофа "`" и двойные кавычки (возможная
SQL-injection атака)
* Ни одно из PHP предупреждений или сообщений об ошибках не должно
быть доступно пользовательским Web приложениям.
* Должна быть реализована возможность сохранения входящих GET и
POST запросов, в текстовом файле, что позволит использовать
дополнительную Host-based систему обнаружения взлома (HIDS),
например swatch (http://swatch.sourceforge.net/).
---------------------------
Подготовка программного обеспечения
Прежде всего, мы должны загрузить исходники самых последних версий
Apache, PHP и модуля mod_security (http://www.modsecurity.org/).
Модуль будет использоваться, для защиты от CSS и SQL-injection атак.
Затем, загруженное программное обеспечение должно быть распаковано, а
содержание архива - помещено в основной каталог. Исходники модуля
mod_security должны быть помещены в каталог Apaсhe
"src/modules/extra":
gzip -dc apache_1.3.27.tar.gz | tar xvf -
gzip -dc php-4.3.2.tar.gz | tar xvf -
gzip -dc mod_security_1.5.tar.gz | tar xvf -
cp mod_security_1.5/apache1/mod_security.c
apache_1.3.27/src/modules/extra/
Если существуют любые доступные патчи защиты к вышеупомянутому
программному обеспечению, то они должны быть загружены и выполнены.
Перед компиляцией программы, мы должны определиться в одном из трех
методов инсталляции PHP:
* Как статический модуль Web сервера
* Как динамический модуль Web сервера
* Как интерпретатор CGI
Каждый из этих методов имеет свои преимущества и недостатки.
Компиляция PHP, как статического модуля, принесет пользу от улучшения
производительности Web сервера, но при апгрейде PHP до более новой
версии придется перекомпилировать весь Web сервер. Компиляция PHP как
динамического модуля, позволяет избежать этого недостатка, но
производительность WEB сервера будет уменьшена приблизительно на 5%, и
был бы необходим еще один модуль: mod_so. Третий метод состоит в
установке PHP как интерпретатора CGI - вместе с механизмом Apache -
suEXEC, что является весьма интересным решением. К сожалению, при
неправильной установке этот метод может представлять серьезную угрозу
защите.
Для лучшей защиты и производительности, лучшим выбором, является
компиляция PHP как статического модуля. Именно поэтому остальная часть
статьи основана на этом методе инсталляции.
---------------------------
Установка PHP
Вообще, как описано в предыдущей статье, инсталляционный процесс
Apache с PHP очень похож на процесс установки Apache без PHP,
Единственное различие - использование двух дополнительных модулей:
mod_PHP и mod_security.
Как и в предыдущей статье, мы начнем с создания учетной записи и
группы, называемых "apache". Для этого мы должны подготовить Web
сервер Apache следующим образом:
cd apache_1.3.27
./configure
И откомпилировать PHP модуль:
cd ../php-4.3.2
./configure --with-mysql=/usr/local/mysql
--with-apache=../apache_1.3.27 --enable-safe-mode
make
su
make install
Затем мы перемещаемся в каталог с Apache и продолжаем установку:
cd ../apache_1.3.27
./configure --prefix=/usr/local/apache --disable-module=all
--server-uid=apache --server-gid=apache --enable-module=access
--enable-module=log_config --enable-module=dir --enable-module=mime
--enable-module=auth --activate-module=src/modules/extra/mod_security
--enable-module=security --activate-module=src/modules/php4/libphp4.a
make
su
make install
chown -R root:sys /usr/local/apache
В команде "./configure", используются только те модули, которые
являются необходимыми для выполнения функциональных возможностей и
предложений по защите. Выбор модулей был детально обсужден в
предыдущей статье. В следующем шаге мы должны возвратиться к каталогу
PHP и скопировать файл конфигурации PHP:
cd ../php-4.3.2
mkdir /usr/local/lib
chmod 755 /usr/local/lib
cp php.ini-recommended /usr/local/lib/php.ini
chown root:sys /usr/local/lib/php.ini
chmod 644 /usr/local/lib/php.ini
Для сценариев PddType application/x-httpd-php .phpHP, которые будут
обрабатываться Web сервером Apache, к
/usr/local/Apache/conf/httpd.conf должна быть добавлена следующая
строка:
AddType application/x-httpd-php .php
В этом пункте мы можем попробовать запустить и проверить Apache, в
случае если PHP должным образом связывается с MySQL. Достигнуть этого
можно, используя сценарий "test.PHP", со следующим содержанием:
(значения "user_name" и "password" должны быть изменены в соответствии
с установками базы данных):
<html><body>
<?php
$link = mysql_connect("localhost", "user_name", "password")
or die;
print "Everything works OK!";
mysql_close($link);
?>
</body></html>
Вышеупомянутая web-страница может просматриваться в любом
WEB-браузере. Если команды PHP нормально интерпретируются и
установлено подключение к MySQL, то можно начать защиту программного
обеспечения. Если нет - то необходимо проанализировали логи Apache и
MySQL и устранить причину проблемы.
---------------------------
Chrooting сервер
Первым шагом в защите сервера, должна быть подготовка chrooted
среды, к Apache серверу с PHP модулем.
этом пункте, необходимо выполнить все шаги, описанные в разделе
"Chrooting сервер" предыдущей статьи. Кроме того, перед первым
запуском Apache в chrooted среде, нужно скопировать следующие
библиотеки (они необходимы для должной работы PHP):
cp /usr/local/mysql/lib/mysql/libmysqlclient.so.12
/chroot/httpd/usr/lib/
cp /usr/lib/libm.so.2 /chroot/httpd/usr/lib/
cp /usr/lib/libz.so.2 /chroot/httpd/usr/lib/
Необходимо также скопировать файл конфигурации PHP:
umask 022
mkdir -p /chroot/httpd/usr/local/lib
cp /usr/local/lib/php.ini /chroot/httpd/usr/local/lib/
и создать каталог /chroot/httpd/tmp. Владелецем каталога должен быть
корневой каталог, а права доступа должны быть установлены в 1777.
После создания новой среды необходимо проверить правильность,
выполнения Apache:
chroot /chroot/httpd /usr/local/apache/bin/httpd
Прежде, чем начать конфигуриование PHP, необходимо учесть еще одну
очень важную деталь - связь между PHP и MySQL. Поскольку PHP
связывается с MySQL локально, используя /tmp/MySQL.sock socket,
размещение PHP в chrooted среде означает, что они не могут связываться
друг с другом. Для решения этой проблемы, каждый раз при выполнении
MySQL, необходимо создавать постоянную связь с Apache chrooted средой:
Ln/tmp/MySQL.sock/chroot/httpd/tmp/
Для создания связи между PHP и MySQL, "/tmp/MySQL.sock" socket и
каталог "/chroot/httpd/tmp", должны быть физически размещены в том же
самом filesystem (постоянные связи не работают между filesystems).
---------------------------
Конфигурирование PHP
Процесс защиты сервера Apache, был описан в предыдущей статье, поэтому
отправной точкой, мы будем считать файл конфигурации, который был в
ней представлен. Для того чтобы Apache мог обрабатывать PHP сценарии,
необходимо к httpd.conf добавить следующие строки:
AddModule mod_php4.c
AddType application/x-httpd-php .php
AddType application/x-httpd-php .inc
AddType application/x-httpd-php .class
Стоит обратить внимание, на то что помимо "*.PHP", есть еще два
расширения, определяющие PHP сценарии: "*.inc" и "*.class".
Программисты часто включают дополнительные файлы, с этими расширением.
Поскольку, по умолчанию, файлы с этими расширениями обрабатываются как
постоянные файлы, то их загрузка покажет исходный текст, содержащийся
в них. Это может привести к раскрытию паролей или другой
чувствительной информации.
Необходимо также сделать несколько изменений в файле конфигурации PHP
(/chroot/httpd/usr/local/lib/PHP.ini). Ниже представлены наиболее
важные из них, которые приводят к улучшению защиты PHP:
safe_mode = On
Активизируя параметр safe_mode, PHP сценарий может осуществлять доступ
к файлам только в том случае, когда их владелец - владелец сценариев
PHP. Это является одним из наиболее важных механизмов защиты,
встроенных в PHP, эффективно противодействует взлому, и добавляет
много ограничений, затрудняющих несанкционированные попытки доступа к
системным файлам (например/etc/paswd).
safe_mode_gid = Off
Когда safe_mode включен, а safe_mode_gid выключен, PHP сценарии имеют
доступ к файлам не только, когда UIDs тот же самый, но и когда группа
владельца сценария PHP такая же как и группа владельца файла.
open_basedir = directory[:...]
Когда включен параметр open_basedir, PHP может обращаться только к
файлам, размещенным в указанных каталогах (и подкаталогах).
safe_mode_exec_dir = directory[:...]
Когда включен параметр safe_mode, system(), Exec() и другие функции
запускающие системные программы не смогут запускать эти программы,
если они не находятся в указанном каталоге.
expose_php = Off
Выключение параметра "expose_PHP" приводит к к тому, что PHP не будет
раскрывать информацию о себе в заголовках HTTP, которые отсылаются
клиентам в ответ на Web запросы.
register_globals = Off
Когда включен параметр register_globals, все EGPCS переменные
(Environment, GET, POST, Cookie and Server) автоматически объявляются
как глобальные. Поскольку это может привести к серьезной угрозе
защиты, настоятельно рекомендуется отключить этот параметр (начиная с
версии 4.2.0, этот параметр по умолчанию отключен)
display_errors = Off
При отключенном параметре display_errors, не отображаются PHP ошибки и
предупреждения. Поскольку такие предупреждения часто показывают важную
информацию, например: пути, SQL запросы и т.д., то настоятельно
рекомендуется отключать этот параметр на производственных серверах.
log_errors = On
Когда включен параметр log_errors, все предупреждения и ошибки
регистрируются в файле, определенном параметром error_log. Если этот
файл не доступен, то информация о предупреждениях и ошибках
регистрируется сервером Apache.
error_log = filename
Этот параметр определяет имя файла, используемого для хранения
информации о предупреждениях и ошибках (внимание: этот файл должен
быть доступен для записи пользователям или группе apache)
Кроме того, должно быть принято во внимание изменение в расширениях
файлов. Например *.php в *.asp, *.dhtml или даже *.html. Такая замена
не дает потенциальным взломщикам узнать, используемую server-side
технологию. Чтобы заменить расширения необходимо все *.php файлы
переименовать, к примеру в *.dhtml, а в
/chroot/httpd/usr/local/apache/conf/httpd.conf, необходимо изменить
следующую строку:
AddType application/x-httpd-php .php
На новую:
AddType application/x-httpd-php .dhtml
Благодаря этому, Web пользователи не будут видеть *.PHP расширение в
адресе URL, что сразу же показывает на использование PHP технологии на
сервере.
---------------------------
Защита от CSS и SQL injection нападений.
Предыдущими шагами в защите сервера были регистрация GET и POST
запросов и осуществления защиты от Cross-Site-Scripting и SQL
injection атак. Для оуществления этого, необходимо использовать модуль
mod_security, которой активизируется, добавлением в httpd.conf
следующей строки:
AddModule mod_security.c
Для включения регистрации GET и POST запросов, необходимо добавить к
httpd.conf следующий раздел:
<IfModule mod_security.c>
AddHandler application/x-httpd-php .php
SecAuditEngine On
SecAuditLog logs/audit_log
SecFilterScanPOST On
SecFilterEngine On
</IfModule>
Вышеупомянутые команды активизируют Audit Engine, который отвечает за
регистрацию запросов, и Filtering POST Engine, который осуществляет
возможность регистрации POST запросов. Для защиты Web-приложений
от CSS атак перед " </IfModule> " должны быть вставлены следующие
строки:
SecFilterDefaultAction "deny,log,status:500"
SecFilter " < (. | \n) + > "
Первая строка необходима для возврата сервером сообщения "Internal
Server Error", в случае если запрос содержит фразу поиска из
любой переменной SecFilter. Вторая строка устанавливает фильтр поиска
HTML тэгов в запросах POST и GET.
Одной из типичных сигнатур SQL injection атаки является появление
апострофа (') или двойной кавычки (") в GET или POST запросе. Отклоняя
все запросы, содержащие эти символы, мы можем затруднить
использование SQL injection методики:
SecFilter "'"
SecFilter "\" "
Обратите внимание, что фильтрация символов <,>, ', " , позволяющая нам
защищаться от CSS и SQL injection атак, может привести к некорректному
функционированию PHP приложения. Это происходит из-за
того, что пользователи не могут использовать эти символы в HTML
формах. Для решения этой проблемы можно со стороны пользователя
использовать язык JavaScript, который должен заменить запрещенные
символы специальными отметками, например *lt; *gt; *quot; и т.д.
---------------------------
Заключение
Достижение высокого уровня защиты Web сервера, использующего серверные
технологии (PHP, ASP, JSP и т.д.) на практике является очень трудной
задачей. Сам характер взаимодействий с Web сервером, существенным
способом уменьшает его защиту. Именно поэтому серверные
сценарии должны использоваться только там, где это абсолютно
необходимо.
Методы, описанные в этой статье, позволяют нам уменьшить риск
успешного взлома, в случае нахождения новой уязвимости в Apache, PHP
или даже в Web приложении. Конечно, статья не дает исчерпывающей
информации по защите PHP технологии, здесь представлены только
основные методы. Их применение увеличивает уровень защиты сервера, но
нельзя забывать, что защита всей среды зависит не только от защиты
Apache или конфигурации PHP, но также и от основного -
непосредственно защиты Web приложения.