Web

Защита веб-серверов PHP

PHP-приложения имеют репутацию приложений с проблемами безопасности выше среднего уровня. Какие методы настройки вы используете для обеспечения максимальной безопасности приложения?

Я ищу такие идеи, как:

  1. Использование усиленного PHP/Suhosin;

  2. Использование mod_security;

  3. Отключение register_globals и allow_url_fopen в php.ini.

Обычно я использую Linux, но мне можно предлагать решения и для Windows.

Ответ 1

Используйте директиву open_basedir, чтобы ограничить ваши PHP-скрипты их домашним каталогом и дополнительными каталогами приложений. Это очень эффективно само по себе.

Используйте hardened php, потому что это ничего не стоит и может помочь. Используйте suPHP, чтобы PHP-скрипты выполнялись от имени владельца файла (один пользователь на сайт) и избегайте использования файлов с плохими разрешениями, такими как 777... suPHP также может позволить вам иметь один php.ini на сайт, чтобы недопустимые требования одного сайта не разрушили все.

Mod_security это большой плюс, но его нужно корректно использовать и настраивать.

Ответ 2

По моему опыту, большинство уязвимостей на сайтах на базе PHP являются результатом плохого дизайна (сайта), а не недостатков самого PHP.

Несколько кратких советов:

  1. Универсально фильтруйте входные данные, экранируйте выходные. Уточнение: filter не означает escape, это означает «если я найду что-то подозрительное в этом вводе пользователя, вызовите отказ отправки и скажите пользователю повторить ввод».

  2. Вместо того чтобы использовать escapeshellcmd(), просто не позволяйте пользовательскому вводу выполняться в оболочке. Это опасно и, вероятно, никогда не понадобится.

  3. Не вызывайте функции типа phpinfo() на рабочем сайте (а если вызываете, смотрите ниже*).

  4. При разработке веб-приложения всегда думайте о том, «является ли это возможным вектором атаки?». Скажем, SQL-инъекция. Если ответ «да», подключите его немедленно. Безопасность никогда не является лишней.

  5. Никогда не выводите необработанные ошибки пользователю; это означает установку в php.ini параметров display_errors = Off, log_errors = On. Отлавливайте ошибки во время выполнения и выводите что-нибудь понятное. Возьмем в качестве примера кит Twitter: он не дает пользователю информацию на уровне отладки, а просто говорит: «Упс, что-то сломалось, пожалуйста, обновите».

*Вы также можете заглянуть в небольшое сообщение, которое я написал под названием «Securing phpinfo(), sort of».  Это была моя идея, чтобы (в некоторой степени) защитить phpinfo(), если я каким-то образом забыл удалить его на рабочем сайте.

В более общем смысле некоторые разработчики пишут обертки для чувствительных функций, которые проверяют, установлен ли флаг «production site» или нет, и отключают чувствительную функцию в production.

Ответ 3

Рассмотрите возможность настройки open_basedir на основе «для каждого сайта». open_basedir это настройка php.ini, которая не позволит вашим скриптам обращаться к файлам вне определенного белого списка. Если на вашем сервере размещено несколько сайтов, это не позволит одному сайту читать настройки базы данных другого сайта. Это также не позволит php-скрипту получить доступ/изменять основные системные файлы. Open basedir легко настроить, просто добавьте строку «php_admin_value open_basedir /my/list/of/folders:/as/a/colon/seperated/list» в каждый Apache vhost.

Также рассмотрите возможность отключения механизма PHP скриптов для всех сайтов/папок, которые не должны содержать PHP скрипты (например, папка загруженных изображений). Опять же, это просто, добавьте «php_admin_value engine off» ко всем виртуальным хостам Apache, которым не нужен php. Чтобы отключить PHP в каталоге, добавьте то же самое в тег Directory.

Установите как можно более жесткие разрешения на файлы, избегайте доступа на запись к PHP-скриптам для пользователя Apache, это не позволит запущенному скрипту изменить себя или другие скрипты на том же сайте/сервере. По возможности избегайте разрешений 777, выясните минимальные разрешения, необходимые для работы приложения, и используйте их.

Если вы размещаете несколько сайтов, каждый со своей собственной базой данных, используйте отдельного пользователя MySQL/Postgres для каждого и установите разрешения для каждого пользователя так, чтобы он имел доступ только к соответствующим базам данных. Это предотвратит вмешательство неавторизованного скрипта в базу данных другого приложения.

Suosin, HardenedPHP, mod_security и т. п. также полезны, но используйте их в дополнение к жестко заблокированной конфигурации, а не вместо нее.

Ответ 4

Вы ищете базовые предложения по брандмауэру/топологии? Мне нравится идея использования таких вещей, как pound, для предотвращения доступа непосредственно к веб-серверу PHP из интернета. Таким образом вы также сможете отделить веб-сервер от других частей вашей сети.

Схожие статьи

Web

Сортировка многомерного массива по нескольким столбцам

Web

Как экранировать строки в SQL Server с помощью PHP

Web

Отладка Curl в PHP

Web

Почему Laravel удаляет данные связанной модели по user_id в загруженной функции модели User