Январь 11, 2006

Фильтрация данных в PHP

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

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

Прежде всего, следует фильтровать данные, которые передает пользователь осознанно - в основном, это данные различных форм. Это может быть пара логин-пароль для входа, пункт голосования и т.п. Например, такая форма


<form action="index.php" method="GET">
<input type="text" name="login">
<input type="text" name "pass">
<input type="submit" value="OK">
</form>

После нажатия кнопки "OK" передаст скрипту index.php два значения - $login и $pass. Как их можно отфильтровать? Пример для переменной $login:


if($login)
{
$login = htmlspecialchars((stripslashes($login)), ENT_QUOTES);
$login = str_replace("/","",$login);
$login = str_replace(".","",$login);
$login = str_replace("`","",$login);
}
else
{
echo "Логин не введен!";
}

В первой строке мы проверяем существование переменной $login, если она существует - идем дальше, если нет - выводим сообщение об ошибке. Затем с помощью функции htmlspecialchars заменяем в этой переменной спецсимволы на их HTML мнемоники. То есть знак `<` меняется на `<`, `&` меняется на `&` и т.д. Функция stripslashes вырезает знак обратного слеша `\`. Далее с помощью str_replace вырезаем знак прямого слеша, точку (иногда бывает полезно) и обратную кавычку.

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


if($login)
{
if (preg_match("/[0-9a-z_]/i", $login))
{
// … действия над логином …
}
else
{
echo "Логин введен неверно!";
}
}
else
{
echo "Логин не введен!";
}

Этот фрагмент кода будет проверять введенный логин на соответствие регулярному выражению `/[0-9a-z_]/i`, которое означает: все цифры + все латинские буквы в любом регистре + знак подчеркивания. Если логин содержит другие символы, то будет показано сообщение об ошибке.

Аналогично фильтруются переменные, получаемые скриптом через URL. В движках сайтов можно встретить что-то вроде таких ссылок:

http://www.site.com/index.php?module=news

Если не фильтровать переменную $module (или $_GET[`module`], если register_globals отключен), то над сайтом могут вытворяться не очень хорошие вещи, вроде XSS. Нужно применять первый приведенный мной скрипт-чистильщик, разумеется, убрав сообщения об ошибках.

Следующее, на чем бы я хотел остановиться - это фильтрация кукисов. Думаю, что даже если вы начинающий программист, то с "плюшками" вы сталкивались, а насчет их проверки даже не задумывались. Зря! Если вы используете SQL-базы данных, то отсутствие проверки кукисов может привести к использованию хакерами SQL-injection. Так как в кукисах, в основном, мы используем определенный тип данных, например, только числа, то проверку данных можно проводить с помощью все тех же регулярных выражений. Допустим, у нас есть кукис "id", в котором хранятся числовые данные. Его проверка:


if($_COOKIE[`id`])
{
if (preg_match("/[0-9]/", $_COOKIE[`id`])
{
// … действия над кукисом …
}
else
{
echo "Хм, странный кукис. Не пойдет!";
}
}


В сети есть огромное количество документации посвященной взлому сайтов, в частности, там показаны различные случаи использования XSS и приемы обхода фильтрации. Но мы то с вами уже умеем защищаться от непрошенных гостей ;)


Автор статьи: SapienS
Сайт: http://wcode.ru/

Комментарии

1. 14.01.06 01:00 От: NMK

$login=',///....fefe';
if (preg_match("/[0-9a-z_]/i", $login)) echo "good login";
в курсе, почему этот код напишет "good login" ;)
Наверное потому, что прежде чем писать статьи, надо разобраться с вопросом безопасности

2. 14.01.06 01:39 От: NMK

Вы наверное удивитесь, но:
$login=",\\\///....fefe";
echo htmlspecialchars(stripslashes($login), ENT_QUOTES);
выдает строку... с обратными слешами :)
вот так вот.
И не очень понятно, зачем обрамлять скобками функцию (stripslashes($login))
естесственно if (preg_match("/[0-9]/", $_COOKIE[`id`])
тоже не будет корректно работать...
Потом, зачем постоянно писать о XSS? Вред от него - минимальный...
И наконец:
$login = str_replace("/","",$login);
$login = str_replace(".","",$login);
$login = str_replace("`","",$login);
можно заменить на:
$login=str_replace(array('/','.','`','\\'),'',$login);
вариантов, конечно, много. Всё зависит от того, где будет использоваться логин...

В общем, статью бы убрать - испортит начинающие умы :(

3. 16.01.06 15:01 От: SapienS

Интересно-интересно %)

"Потом, зачем постоянно писать о XSS? Вред от него - минимальный..."
Ага: http://www.antichat.ru/crackchat/HTML/

"выдает строку... с обратными слешами :)"
Выдержка из офиц. мануала:

string stripslashes (string str)

Возвращает строку с вырезанными обратными слэшами (\' становится ' и так далее). Двойные backslash становятся одинарными.

"можно заменить на:
$login=str_replace(array('/','.','`','\\'),'',$login);"

Конечно, можно! А можно ещё preg_replace или ereg_replace! Вариантов куча...

Я показал ЛИШЬ ПРИМЕР

4. 16.01.06 15:19 От: NMK

string stripslashes (string str)

Возвращает строку с вырезанными обратными слэшами (\' становится ' и так далее). Двойные backslash становятся одинарными.

ну и что )))))
В вашей статье - это не предотвращает проникновение, а лишь чуть усложняет.

antichat конечно может написать про XSS кучу интересного. Понятно, что если введенное пользователем остается на странице, то это может быть опасным. Но это вариант - тот же chat, форум, гостевая книга. Ну и ответвления разные... А в остальном XSS намного сложнее применить. Вред всё же минимальный.

$login=str_replace(array('/','.','`','\\'),'',$login);"
работает быстрее, чем три или четыре подобных, выглядит эффектнее, намного быстрее, чем "ещё preg_replace или ereg_replace". Примеры в статье тоже надо ставить оптимальные.

Потом вы ничего не ответили на "if (preg_match("/[0-9a-z_]/i", $login))" - это серьезнейшая брешь.

А ведь люди могут прочитать эту статью и начать что-то делать.

Так что - без обид - очень плохой пример. Странно, что владелец или совладелец достаточно интересного сайта публикует такие статьи.

5. 16.01.06 18:50 От: NMK

if($_COOKIE[`id`])
{
if (preg_match("/[0-9]/", $_COOKIE[`id`])
{
// … действия над кукисом …
}
else
{
echo "Хм, странный кукис. Не пойдет!";
}
}

заменяется на несложное и более быстрое:
echo (isset($_COOKIE['Id']) && is_numeric($_COOKIE['Id']))?'good':'Хм, странный кукис. Не пойдет!';

if($login)
{
if (preg_match("/[0-9a-z_]/i", $login))

меняется на:
if (isset($login) && preg_match('/^[a-z][0-9a-z_]+$/',$login)) {...}else{...}

меняется на:

чтобы в хистори у браузера не сохранялся пароль и логин... И это как минимум.

6. 16.01.06 18:52 От: NMK

Извините, но комментарии на сайте имеют что-то против форм, поэтому последние вещи не напечатались. В общем, лучше заменить метод пересылки аргументов на method=POST, чтобы в браузере не сохранялся логин и пароль.

7. 28.02.07 00:23 От: Linex

ia oceni rad shto napisanie kamentarii harasho apisani,dlia navichca ata paneatnei!(Sorry za translit)

8. 28.02.07 00:25 От: Linex

Na sheot method=POST mne cajetsea eta samii nadeojnii metad dlia secretnih danih,cto cio scajet na etot sheot
???(Sorry za trenslit)

9. 04.04.07 12:31 От: Александр

Что касается статьи то странно когда вы говорите про "безопасность" вы включаете в это понятие только скриптинг а ведь проверка логина и пралоля во много раз сложнее.

Вот к примеру почему мне запретили в качастве логина использовать предположим свой mail(в нем есть символы отличные от [0-9a-z_])? ведь фактически он уникален и кстати может начинаться и на цифру!

И + ко всему пароль должен проверятся на уровень безопасности, а его следует задавать!

Что касается метода POST то фактически если твое тварение начнут взламывать будет абсолютно наплевать какой метод ты используешь! так как подделать их очень легко и узнать что именно ты отправлял тоже.

Лично мое мнение касательно взлома и безопасности можно сделать несколько уровней защиты. к примеру: пароль должен соответствовать 3-ей группе сложности. форма должна заполнятся от 3 до 60 секуд и т.д.:

Вот к примеру создаем пару полей, в одном хранится значение, а во втором проверочный ключ. Что бы взломщику пришлось помучаться в checkField вставляем то же самое значение + ключевое слово и можно еще чего нибудь привязать к примеру имя поля или id сессии. В таком случае вы аренее будуте уверены в правильности поля field так как вы можете его проверить(Получив данные из формы вы можете повторно зашифровать значение field и сравнить с checkField).


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

Как выбрать метод?

Лично мое мнение что метод GET следует использовать там где отправив форму вы могли бы на полученный результат отправить ссылку. Если такого не нужно (авторизация), то следуует использовать POST.

Бывает ситуация когда надо иметь возможность передать ссылку но она получается СЛИШКОМ длинной. В таком случае есть такой вариант:
1. сохранять запрос
2. присваивать ему идентификатор
3. в адресную строку передавать его идентификатор запроса.

10. 02.05.07 00:40 От: Андрей

Любите ли вы деньги?
А кто их не любит?! 
Но их трудно заработать в большом количестве не обманув или не кинув кого нибудь.
В этой статье я расскажу Вам как без обмана и не нарушая закона можно заработать.
В этой статье описан способ поправить своё финансовое положение, не бросая основной работы и в тоже время уделяя своему новому заработку ровно столько времени, сколько вы можете себе позволить.

Наткнулся на эту статью на одном из форумов и не решался попробовать. Когда же решился, то был приятно удивлен. Я начал зарабатывать в интернете!!!
В ней говорилось, что можно заработать тысячи долларов за пару недель при вложении всего 6$.

Дальше в ней объяснялось, что нужно послать по 1$ на 6 Интернет-кошельков,
перечисленных ниже. Потом вычеркнуть первый кошелёк из списка, тем самым, сместив список на одну строчку вверх. Шестая остаётся свободной.

Куда и нужно вписать номер своего кошелька. И оставить изменённое сообщение как МИНИУМ на 200 разных форумах.

Сама идея была проста и гениальна одновременно!
Уверен, что её автор уже давно не ходит на работу, как мы с вами!!!
Жаль, решение пришло не сразу! Были и у меня сомнения.

В конце концов, что можно было потерять кроме этих несчастных 6$?
Это гораздо МЕНЬШЕ 180 рублей - и за такие деньги можно купить лишь
БУТЫЛКУ коньяка, да и то совсем не высокого качества.
И я решился…

Через 5 дней томительных ожиданий, не выдержал и заглянул в свой кошелёк.
Там появились деньги!!!
Причём ровно столько, что бы окупились все первоначальные затраты…
Я был не просто приятно удивлён!!! Я был в шоке!!!

В первую неделю пришло ВСЕГО 25$. Думал, что на этом всё и кончится...
Ага, как же!!! К концу второй недели там было уже 500$. К середине 3-ей перевалило за 1000$. В конце месяца я насчитал порядка 20000$, и эта сумма продолжала упорно расти, причём ОЧЕНЬ-ОЧЕНЬ БЫСТРО!!!

Я не верил, что это работает, пока не начал получать переводы со всего Мира!!! До этого даже не знал, что бывают такие лёгкие деньги!
А оказалось, ОНИ ЕСТЬ!

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

Вот те самые 3 шага к вашему успеху:

1. Если у Вас нет тех самых 6$, то Вам нужно зарегистрироваться в системе WebMoney Transfer, которая находится на http://www.webmoney.ru/.

Хорошенько ознакомьтесь с данной системой, как она работает, выберите оптимальный для себя вариант пополнения кошелька.

Затем внесите 6 WMZ (карточки минимум 10 WMZ продаются в обычных ларьках) на Ваш WMZ кошелёк (он начинается с буквы Z).

2. Отправьте на первый номер из ниже перечисленных WMZ кошельков 1$,
в поле напишите: "Пожалуйста, внесите меня в список
WMZ кошельков". Всё, что Вы сделали - это создали некую услугу и,
САМОЕ ГЛАВНОЕ, это абсолютно легально!!! Вы просите законный сервис,
за который платите.

Теперь отправьте во 2,3,4,5,6 WMZ кошельки также по 1$, но уже в поле ничего писать не нужно!

Вот, наконец, и список этих кошельков:
1. Z405187848629 (здесь пишете ПРИМЕЧАНИЕ)
2. Z362740119815 (здесь и дальше ничего не писать!)
3. Z395135051539
4. Z275936537647
5. Z109222301360
6. Z393935252484

ВНИМАНИЕ!!!
Нужно вычеркнуть из этого списка ПЕРВЫЙ кошелек, и переместить 2-ой кошелёк на место 1-го, который Вы стёрли, 3-ий на место 2-го,4-ый на место 3-го, 5-ый на место 4-го и 6-ой на место 5-го! А в шестой номер, который оказался пустым, впишите номер Вашего WMZ КОШЕЛЬКА!!!

3. САМОЕ ГЛАВНОЕ!!!
Поместить эту статью МИНИМУМ на 200 ФОРУМАХ и НОВОСТНЫХ ЛЕНТАХ (News Groups)!!!

ПОЙМИТЕ: Чем больше Вы разместите, тем выше будет ВАШ доход!!!
И этот доход будет НАПРЯМУЮ ЗАВИСЕТЬ ОТ ВАС И ТОЛЬКО ОТ ВАС!!!

Делайте в моей статье, какие угодно Вам изменения, только
СОХРАНИТЕ ГЛАВНУЮ ИДЕЮ!

Прошу Вас: ПРОЧТИТЕ ЭТО ЕЩЁ РАЗ!!!
Следуйте инструкциям, и деньги начнут поступать и на Ваш кошелёк!!!

Согласитесь, нет ничего ПРОЩЕ!!!
И ВАЖНО, ВСЁ ЛЕГАЛЬНО!!!
И Ваш вклад составляет всего 6$...
И ЭТО РАБОТАЕТ, ПРИЧЁМ УЖЕ ОЧЕНЬ ДАВНО!!!

Займитесь этим СЕЙЧАС!!! ВРЕМЯ ТЕПЕРЬ – ЭТО ВАШИ ДЕНЬГИ!!!
Не стоит откладывать то, что МОЖЕТ СДЕЛАТЬ ВАС БОГАТЫМ уже завтра.

А теперь, разрешите, я расскажу ВАМ, как это работает и самое главное ПОЧЕМУ?

Скажем, из 200 размещений ВЫ получите, к примеру, 5 ответов (ну очень-очень маленькая и низкая цифра)!!!

Значит, ВЫ получите +5$, находясь на 6-ой позиции в списке!!!
Теперь эти 5 людей сделают по 200 размещений каждый МИНИМУМ с ВАШИМ кошельком на 5-ой позиции, и только 5 людей отвечают тем первым пяти - это уже +25$!!!

Дальше эти 25 людей делают по 200 размещений с Вашим кошельком на 4-ой строчке (потому что вписывают свои) и только 5 отвечают – Ваш доход +125$!!! Теперь эти 125 людей, разместив и получив только 5 ответов, дают Вам +625$ прибыли (А вы уже на 3-ей строчке)!!!

Дальше ещё прикольнее: эти 625 людей делают по МИНИМУМ 200 размещений с Вами на 2-ой строчке и только 5 людей отвечают - это уже +3125$!!!

Ну а самое интересное - это то, что эти 3125 человек делают по 200 размещений каждый с вами уже на 1-ой строчке и им отвечают опять только 5 людей, то Ваш доход +15 625$!!!!!!

Внушительная цифра? Если нет, то подсчитайте, что получится.
В том случае, когда откликнутся не 5, а 10 человек!!! Теперь-то впечатляет?

И это всё за первоначальный сверхнизкий вклад – в 6$!!! Неплохо, да?

Когда Вас в списке уже нет, Вы просто высылаете опять 6$ в те же кошельки, что и в первый раз (для этого сохраните эту статью в БЛОКНОТЕ) и опять, переместив номера кошельков, удалив первый, ставите свой номер на 6-ую позицию и опять размещаете!!!

Ну, так как?
Потратите ли Вы всего 6$,чтобы узнать, что это работает!!! ДА ЕЩЁ КАК!!!

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

КЛЯНУСЬ ВАМ!!! ТАК И ЕСТЬ!!! ВАША ЖИЗНЬ МОЖЕТ ИЗМЕНИТЬСЯ!!!

Любой Пессимист скажет: А вдруг мне никто ничего не пришлёт?

Позвольте развеять ваши последние сомнения!
Ведь каждый день в Интернете появляются от 20000 до 50000 тысяч новых пользователей!!!

По прогнозам самого Билл Гейтса, только в России к 2006 году количество пользователей Интернета увеличится с нынешних 9 миллионов человек, до 21 миллиона!!! Каковы шансы, что они захотят попробовать себя в чём-то новом?

Вы себе можете представить, что 1000 людей со всего мира присоединяются к Интернету и читают эти статьи каждый день!!! Точно так же, как и Вы сейчас читаете эту!

ГЛАВНОЕ ПОМНИТЕ: ЧЕСТНОСТЬ И ТОЛЬКО ЧЕСТНОСТЬ ЛЮДЕЙ позволяет процветать этому бизнесу!!! Я искренне надеюсь, что вы именно такой человек.

Прежде чем что-нибудь получить, обязательно нужно что-то дать взамен!!!
Так устроен этот Мир!
А чтобы получить ещё больше, придётся ещё больше дать!!!

А как распространять информацию в форумах?

1. Открываем любой поисковик: rambler.ru , yandex.ru, google.ru, aport.ru
2. Пишем в строке поиска фразу: "форум флейм" (без кавычек)
3. Поисковик найдёт тысячи страниц, ссылки на которые сразу приводят на страницу для заполнения новой темы форума, а также можно вносить эту статью как цитату в различных форумах.
4. Используйте обычный переводчик для перевода этого текста и размещайте их
на форумах других стран. Легко и просто!!!

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

ДЕЙСТВУЙТЕ! Вам воздастся сторицей. Успех – на кончиках ваших пальцев.

11. 05.05.07 11:03 От: Yaya spam@tek.ua

вообще то давно придумали strip_tags, незнали?

Ваш комментарий

Обсудить на форуме?

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