Домой / Группы / PHP уязвимость и защита от PHP инъекций. Правила безопасного программирования на PHP. Проверенные способы защиты PHP Беззащитный category php

PHP уязвимость и защита от PHP инъекций. Правила безопасного программирования на PHP. Проверенные способы защиты PHP Беззащитный category php

PHP - это один из самых популярных серверных языков программирования с открытым исходным кодом. Он используется не только для создания сайтов, но и в качестве языка программирования общего назначения, а также для написания серверной части различных веб-приложений.

Выполнять скрипты на PHP могут веб-серверы Apache, Nginx и Lighttpd. Также PHP может выполняться интерпретатором прямо из командной строки. Но поскольку PHP установлен на сервере, он может создать ряд проблем с безопасностью, поэтому его нужно применять осторожно.

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

Все приведенные ниже советы рассчитаны на то, что PHP работает под управлением Nginx или Apache, сам интерпретатор PHP недоступен из внешней сети. А теперь, перейдем к рассмотрению того как выполняется защита php кода, сайта и сервера в целом.

1. Знайте врага в лицо

Приложения на основе PHP могут подвергаться различным типам атак, вот основные из них:

  • XSS - это уязвимость в веб-приложениях, с помощью которой злоумышленники могут выполнять произвольный JavaScript код в браузере пользователей, и таким образом, украсть его данные. Возникает из-за отсутствия проверки на данных в скриптах на правильность;
  • SQL инъекция - это уязвимость в коде работы с базой данных. Если пользовательский ввод неверно фильтруется скриптом, и используется для формирования запроса к базе данных, то злоумышленники могут выполнить любые запросы к базе данных. Для предотвращения такой проблемы рекомендуется фильтровать данные функцией mysql_real_escape_string() перед отправкой запроса;
  • - позволяет посетителю загружать файлы на ваш сервер. Загрузив определенный тип файлов, пользователи могут получить доступ к системе или даже украсть информацию из базы данных, поэтому нужно следить чтобы можно было загружать только картинки;
  • Удаленное выполнение - злоумышленник может удаленно выполнять php файлы, которые есть на сервере, поэтому вместе с возможностью загрузки PHP файлов это представляет серьезную опасность;
  • Eval() - позволяет выполнить код PHP, переданный в строке, часто используется злоумышленниками, чтобы скрыть свой код на вашем сервере;
  • CSRF атака - позволяет заставить пользователя выполнить нежелательные действия в веб-приложениях. Если пользователь является администратором, это может поставить под угрозу все приложение.
2. Используйте только необходимые модули

Чтобы посмотреть все скомпилированные модули PHP выполните команду:

Рекомендуется использовать только самые необходимые модули, чтобы увеличить безопасность. Например, вы можете отключить модуль sqlite. Для этого можно удалить его конфигурационный файл в /etc/php5/conf.d/. Но для полного удаления нужно пересобрать PHP без этого модуля.

3. Избегайте утечек информации

В конфигурационном файле php.ini есть строчка:

expose_php = Off

Если установлено значение On, то PHP будет отправлять версию PHP в ответ на все запросы в заголовке X-Powered-By. Также рекомендуется скрыть версию Apache и другую информацию. Защита php от взлома, это не только аккуратное программирование, но и сокрытие информации о системе.

4. Отключите динамические расширения

PHP поддерживает динамическую загрузку расширений. По умолчанию загружаются все расширения, конфигурационные файлы которых есть в /etc/php/conf.d/. Также загружаются модули, которые указаны директивой extension в основном конфиге php.ini. Мы можете удалить ненужное.

5. Вывод ошибок

Сообщения об ошибках содержат много информации, не позволяйте их смотреть всем пользователям сайта. Приведите директиву display_errors к такому виду:

display_errors = Off

Убедитесь, что вы сохраняете все ошибки в лог файл:

log_errors = On
error_log = /var/log/httpd/php_scripts_error.log

6. Запретите загрузку файлов

file_uploads = Off

Но если такая функция необходима, то лучше ограничить размер файла:

file_uploads = On
upload_max_filesize = 1M

Пользователи смогут загружать файлы размером не более 1 мегабайт, так безопасность в php будет больше.

6. Отключите удаленное выполнение кода

Если параметр allow_url_fopen включен, php может использовать такие файловые функции, как file_get_contents . С помощью нее скрипт может загружать файлы из удаленных серверов. Программисты часто забывают выполнить надлежащую фильтрацию данных, и тем самым открывают уязвимость. Для отключения измените директиву:

allow_url_include = Off

7. Включите безопасный режим SQL

В безопасном режиме SQL, интерпретатор игнорирует все аргументы, передаваемые в функции mysql_connect и mysql_pcconnect. Но в таком режиме будут работать не все скрипты, например, не будет работать WordPress, так что используйте аккуратно. Для включения добавьте директиву:

magic_quotes_gpc=Off

9. Контролируйте размер POST

Метод POST используется, когда браузер хочет передать веб-серверу определенное количество данных как часть запроса, например, при загрузке файла. Злоумышленники могут использовать большие запросы, чтобы истратить ресурсы сервера. Поэтому размер лучше ограничить:

post_max_size=1K

10. Контролируйте ресурсы

Вы можете указать максимальное время выполнения для каждого скрипта, максимальное количество памяти и максимальное время чтения данных, это увеличит безопасность сайта php в плане DOS атак:

max_execution_time = 30
max_input_time = 30
memory_limit = 40M

11. Отключите опасные функции

PHP содержит множество функций, которые могут использоваться для взлома сервера, например, те, которые позволяют выполнять команды оболочки. Чтобы отключить, достаточно их перечислить в директиве disable_functions:

disable_functions =exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

12. Настройте Fastcgi для лучшей безопасности

PHP может работать через FastCGI, это уменьшает использование памяти вашего веб-сервера. Нужно включить директиву force_redirect чтобы предотвратить прямое выполнение php скриптов из строки запроса, например, cgi-bin/php/hackerdir/backdoor.php. Для этого добавьте:

cgi.force_redirect=On

13. UID и GID интерпретатора PHP

Если вы используете внешний FastCGI сервер, то нужно чтобы он был запущен не от пользователя root. Запускайте php от имени непривелигированного пользователя. Как вы знаете, у PHP есть функции, которые позволяют выполнять команды оболочки. Очень небезопасно, если они будут выполняться от суперпользователя.

14. Ограничение доступа к файловой системе

Директива open_basedir позволяет установить каталог, в котором php может получить доступ к файлам с помощью таких функций, как fopen, file_get_contents и т д. Если файл находится вне этой директории PHP откажется его открывать. Вы даже не сможете использовать символические ссылки.

open_basedir = "/var/www/html/"

15. Путь для хранения сессий

Нужна не только защита php сайта, чтобы скрипты не смогли причинить вред системе, но и чтобы пользователи не могли получить доступ к файлам php. Сессии в php позволяют сохранить определенную информацию между обращениями пользователя. Путь, где будет храниться эта информация указан в файле /etc/php/php.ini. Убедитесь, что этот путь находится вне /var/www/ и недоступен для чтения или записи для других пользователей системы.

upload_tmp_dir = "/var/lib/php/session"

16. Держите программное обеспечение в актуальном состоянии

Все программы могут содержать различные уязвимости, поэтому важно выполнять регулярное обновление системы, чтобы вовремя применить все патчи безопасности. Нужно обновлять не только PHP, а весь программный стек, в том числе Apache.

17. Используйте SELinux

SELinux - это система безопасности, используемая по умолчанию в RedHat. Ее можно использовать для предотвращения несанкционированного доступа к файлам и ресурсам. Например, вы можете установить политики безопасности для веб-сервера Apache или отдельного сервера PHP. Это тоже отличная защита PHP и не только.

18. Установите mod_security

Это модуль Apache для обнаружения и предотвращения в веб-приложения. Он может защитить php и ваше приложение от XSS и SQL-Inj атак. Например, чтобы не позволять открывать файлы в /etc/ после установки модуля добавьте в конфигурационный файл Apache:

А для предотвращения SQL инъекций:

SecFilter "delete[[:space:]]+from"
SecFilter "select.+from"

19. Просматривайте журналы

Регулярно просматривайте файлы журналов Apache и PHP, вы сможете получить некоторые представление о том, как работает сервер и проверить уровень безопасности.

tail -f /var/log/httpd/error_log
$ tail -f /var/log/httpd/php_scripts_error.log

Выводы

В этой статье мы рассмотрели несколько способов увеличить безопасность сайта PHP. Они помогут вам держать свой сервер в максимальной безопасности. Возможно, это не все доступные варианты, если вы знаете другие способы, напишите в комментариях.

На завершение лекция про безопасность написания скриптов в PHP:

Одним из наиболее значимых вопросов для web-программистов является безопасность php-скриптов. Все программисты в той или иной мере используют различные методы чтобы обезопасить свой проект, но, к сожалению, в большинстве случаев используется защита от нескольких уязвимостей, при этом остальные проблемные места даже не рассматриваются.
В данной статье перечислены основные виды уязвимостей PHP и рассмотрены способы защиты от них.

Виды уязвимостей PHP
  • Демонстрация ошибок пользователю
    Смысл: при каких-либо ошибках в коде пользователю выводиться информация об произошедшей ошибке. Не является критичной уязвимостью, но поваляет взломщику получить дополнительную информацию о структуре и работе сервера.
  • Доступность данных о характеристиках системы пользователю
    Смысл: пользователь может получить доступ к данным, дающим представление о системе. Не является критичной уязвимостью, но поваляет взломщику получить дополнительную информацию о структуре и работе сервера. Причина этой уязвимости в ошибках и «недосмотрах» программиста. Примером может служить наличие файла phpinfo.php с одноимённой функцией в свободном доступе.
  • Доступность данных о программном коде пользователю
    Смысл: пользователь может получить доступ к программным кодам модулей, имеющих расширение, отличное от php . Является критичной уязвимостью, так как позваляет взломщику получить достаточно полную информацию о структуре и работе сервера, выявить его уязвимости.
  • Простые пароли для доступа к административным страницам
    Смысл: взломщик может подобрать простой пароль к административной странице, дающей ему больше возможностей для взлома. Является критичной уязвимостью, так как позваляет взломщику повлиять на работу сервера.
  • Возможность задания глобальных переменных
    Смысл: при неправильных настройках PHP имеется возможность задавать глобальные переменные скрипта, через строку запроса. Является критичной уязвимостью, так как взломщик может влиять на ход работы скрипта в свою пользу.
  • PHP-инъекция
    Смысл: в параметр, определяющий работу PHP с файлами или программным кодом, передаётся ссылка на сторонний программный код или сам код. Является критичной уязвимостью, так как взломщик может выполнять свои скрипты на сервере. Выполнение кода осуществляется при помощи функций: eval(), preg_replace(), require_once(), include_once(), include(), require(), create_function(), readfile(), dir(), fopen() .
  • PHP-инъекция через загрузку файлов
    Смысл: при возможности задании глобальных переменных в параметр, определяющий загружаемый на сервер файл, передаётся ссылка на сторонний программный код или конфиденциальный файл на сервере. Является критичной уязвимостью, так как взломщик может выполнять свои скрипты на сервере или получить доступ к конфиденциальным данным. Данная уязвимость возможна только при возможности задания глобальных переменных и неверной организации механизма загрузки файлов.
  • e-mail-инъекция
    Смысл: в параметр, определяющий работу PHP с электронными письмами, передаётся ссылка на сторонний программный код или сам код. Является критичной уязвимостью, так как взломщик может выполнять свои скрипты на сервере или получить доступ к данным, хранимым у пользователя.
  • SQL-инъекция
    Смысл: в параметр, определяющий SQL-запрос, передаётся данные, образующее запрос для доступа к закрытым данным. Является критичной уязвимостью, так как взломщик может получить конфиденциальные данные, хранимые в базе данных. Для изменения запроса взломщик может использовать следующие конструкции: SELECT, UNION, UPDATE, INSERT, OR, AND .
  • Межсайтовый скриптинг или XSS
    Смысл: в параметр, определяющий выводимые пользователю данные, передаётся сторонний программный код. Является критичной уязвимостью, так как взломщик может получить конфиденциальные данные, хранимые в браузере клиента. Для изменения запроса взломщик использует html-теги.
  • Правила написания безопасного кода на PHP
  • Блокирование вывода ошибок
    Для этого достаточно в программном коде задать error_reporting(0) или в файле.htaccess добавить строку php_flag error_reporting 0
  • Использование сложных паролей для доступа к административным страницам
    Для этого достаточно использовать многозначные пароли, не имеющие семантического значения (например, К7O0iV98dq).
  • Логирование критических действий пользователя
    Не обеспечивает защиту напрямую, но позволяет выявить взломщиков и определить уязвимости, которые они использовали. Для этого действия пользователя и переданные им данные, которые касаются критических моментов работы системы, достаточно записывать в обычный текстовый файл.
    Пример функции логирования и её работы:
    function writelog($typelog, $log_text) {
    $log = fopen("logs/".$typelog.".txt","a+");
    fwrite($log, "$log_text\r\n");
    fclose($log);
    }
    writelog("authorization", date("y.m.d H:m:s")."\t".$_SERVER["REMOTE_ADDR"]."\tУспешный вход");
  • Закрытие доступа к модулям сайта
    Обеспечивает защиту от попыток просмотра их содержимого или выполнения. Для этого достаточно в файле.htaccess настроить доступ к файлам модулей при помощи конструкций FilesMatch и Files .
    Например, мы закрываем доступ ко всем модулям с расширением php , кроме файла capcha.php :
  • Отключение возможности задания глобальных переменных
    Для этого достаточно в настройках сервера задать register_globals = off; или в файле.htaccess добавить строку php_flag register_globals off . Использование ini_set("register_globals",0); проблему не решит так, как переменные задаются до начала выполнения скрипта.
  • Отключение возможности использования удаленных файлов
    Для этого достаточно в настройках сервера задать allow_url_fopen = off; . Это обеспечивает частичную защиту от PHP-инъекций, но не полную, так как взломщик может передавать не ссылку на файл с программным кодом, а сам программный код. Для полной защиты от PHP-инъекций необходимо дополнительно использовать фильтрацию поступивших данных. Иногда данную меру защиты невозможно использовать из-за особенностей работы проекта (нужно обращаться к удалённым файлам).
  • Фильтрация поступающих данных
    Обеспечивает защиту от большенства уязвимостей. Универсального решения не существует. Желательно использовать проверку по «белому» списку символов в совокупности с проверкой на запрещённые слова. «Белым» называется список разрешенных символов. В этот список не должны входить опасные символы, например, . К запрещённым словам можно отнести: script, http, SELECT, UNION, UPDATE, exe, exec, INSERT, tmp , а также html-теги.
    Пример фильтрации поступающих данных:
    // Проверка по белому списку. Допускаются только русские и латинские буквы, цифры и знаки _-
    if (preg_match("/[^(\w)|(А-Яа-я-)|(\s)]/",$text)) {
    $text = "";
    }
    // Фильтрация опасных слов
    if (preg_match("/script|http|||SELECT|UNION|UPDATE|exe|exec|INSERT|tmp/i",$text)) {
    $text = "";
    }
  • Проверка на загрузку файла при помощи HTTP POST
    Обеспечивает защиту от PHP-инъекций через загрузку файлов. Для обеспечения этого загруженные на сервер файлы необходимо проверять функцией is_uploaded_file() или перемещать функцией move_uploaded_file() . Данный вид защиты можно не использовать, если отключена возможность задания глобальных переменных.
  • Экранирование символов кавычек данных, передаваемых в базу данных
    Обеспечивает защиту от SQL-инъекций. Наиболее оптимальным методом является обработка всех поступивших не числовых данных с помощью функции mysql_real_escape_string() . Можно так же использовать автоматическое экранирование, поступающих данных. Для этого достаточно в файле.htaccess добавить строку php_value magic_quotes_gpc on , но этот способ не является надёжным, так как может привести к двойному экранированию.
    Пример экранирования кавычек с помощью функции mysql_real_escape_string() :
    if (!is_numeric($text)) {
    $textrequest = mysql_real_escape_string($text);
    }
  • Преобразование специальных символов в html-сущности перед выводом
    Обеспечивает защиту от XSS. Для этого данные, введенные пользователем, которые могут содержать нежелательные html-тэги, при выводе достаточно обработать функцией htmlspecialchars() . Данный вид защиты можно не использовать, если фильтрация поступающих данных отсеивает опасные html-тэги.
  • Как видите создание продуманной системы безопасности скриптов не такое трудоёмкое дело как кажется.
    Данная статья не претендует на роль учебника по безопасности скриптов, но Я надеюсь, что она подтолкнёт php-программистов использовать более продуманные методы защиты.

    Получает внешний фид и разбирает его на данные (парсит его).

    Функция нужна, чтобы получить RSS фид в виде SimplePie объекта и закэшировать результат.

    Для получения и парсинга фида fetch_feed() использует популярный класс SimplePie . Фид кэшируется и кэш в последствии обновляется каждые 12 часов.

    Данные кэшируются в базу данных во временные опции . Если установлен плагин постоянного объектного кэширования, то функция будет кэшировать не в БД, а в хранилище для объектного кэша.

    Возвращает

    SimplePie/WP_Error. SimplePie объект данных о фиде или объект WP_Error в случае ошибки.

    Использование $feed = fetch_feed($uri); $uri(строка) (обязательный) Ссылка (УРЛ) на фид который нужно получить. В результате по этой ссылке будет получен создан объект (массив) SimplePie.
    По умолчанию: нет Примеры #1. Получим последние 5 записей из фида у внешнего сайта

    Пример, который получает и выводит на экран ссылки на существующий RSS фид. В примере мы ограничиваем вывод только 5-ю последними записями в фиде.

    Поcледние новости с блога blog.ru