Блог


Основы безопасности

Часто на форумах и в разных источниках я встречаю словосочетание "фильтрация данных". Вот и сегодня встретил на одном очень популярном ресурсе, не скажу на каком. Эта фраза заставляет меня передергиваться. Люди, использующие это определение, совершенно не понимают сути вопроса. Это ставит под сомнение не только сиютекущий материал, но и компетентность заявившего сие.

Давайте разберемся, что есть фильтрация. Фильтрация - от слова фильтр. Лезем в википедию и видим:


Фильтр (от лат. filtrum «войлок») понятия, устройства, механизмы, выделяющие (или удаляющие) из исходного объекта некоторую часть с заданными свойствами.

Ключевые слова - выделяющие, удаляющие. Соответственно, если мы фильтруем данные, значит мы волей неволей часть их удаляем. Да! воскликнут авторы сиих опусов. Мы же должны удалить опасные символы!


Теперь внимание, вопрос. Чем это вдруг символы стали опасными? Это красная кнопка такая на клавиатуре наверное, самоликвидатор. Нажмешь на неё, выскакивает алерт: "Вы точно хотите уничтожить данные, весь компьютер и все живое в радиусе 50 метров?"

 

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

Однако проблема есть, да еще какая. Мы же нарушаем целостность данных. Почему текст должен лишиться кавычек, апострофов, бричек и так далее. Почему я не смогу написать <twin>

 

Да нееет! Скажут те самые эксперты. Мы не удаляем! Мы фильтруем с помощью функции htmlspecialchars()!

Эта функция ничего не фильтрует. Она предназначена для того, чтобы заменять штатные символы HTML разметки на эквиваленты, которые интерпретируются браузером, как обычный текст. А не удалять, суть фильтровать. Да, вроде бы все верно. Заменили бричку < на &lt; и спим спокойно. Тег уже не получится. Можно вроде бы писать текст в базу, ничего страшного не произойдет.

 

Но так ли это? Давайте рассмотрим повнимательнее. Что есть таблица в базе данных? Обычный файл. Как может HTML разметка навредить файлу? Ну или базе данных в целом? Да никак не может. Эта разметка работает только в браузере, ни на сервере, ни в СУБД от неё нет никакого вреда. Так что писать в базу данных нужно исходный текст, ни в коем случае не искажать его. А вот на выдаче в поток обязательно подготовить функцией htmlspecialchars(). Другими словами, не базу нужно защищать от "опасных символов", а браузер от базы.

Вот рассмотрим ситуацию.

Допустим вы владелец огромного портала, где десятки и сотни тысяч, а то и миллионы сообщений. Каждое сообщение хранится на одной строке таблицы СУБД. Значит и их сотни тысяч или миллионы.

И вот под покровом ночи злоумышленник окольными путями проник в базу. Угнал трояном пароль, мало ли. Что он сделает, как вы думаете? Дропнет базу? Ну это детский сад, это делают только сопливые школьники-недоучки, которые возомнили себя хацкерами. Через 10 минут сайт будет восстановлен из бэкапа. Настоящий, махровый взломщик (специально не пишу хакер, ибо хакер, это хорошее слово, просто извратили смысл) попытается получить материальную выгоду. Если в руки попал такой крутой ресурс, тут можно озолотиться. Представляете какая охота идет на всяческие Вконтакты, Мамбы и прочие соцсети. 

А в чем выгода. Все просто. Можно разместить на вашем ресурсе рекламу, банеры и прочее дерьмо. А лучше сразу редирект. Человек открывает сообщение, а там javascript, который отправляет его на какой-нибудь жесткий гей-порноресурс. Потому что взломщику не скажешь - а чего это ты перед внесением в базу неотфильтровал их с помощью htmlspecialchars()? А? И сделать при этом грозную мину еще: 

 

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

А если мы готовим выдачу в поток, заменяя штатные символы разметки на эквиваленты, обрабатываем данные функцией htmlspecialchars() непосредственно перед отправкой данных браузеру клиента, то пусть этот скрипт спокойно лежит себе в базе. Это обычный текст и ничего он там не сможет сделать. Вот допустим пример. Я сейчас прямо напишу такой редирект и отправлю в базу:

<script>location.href = "http://sex.com"</script>


Вы еще тут? Ау! Не улетели к порнушникам? И не улетите, ибо это подготовленный текст. А в базе он хранится именно в таком виде, в каком вы его видите на экране.

 

 

Но как же SQL-инъекции? Спросите вы. И будете правы, вопрос очень закономерен. Но подготовка литеральных констант или числовых данных к помещению в запрос ничего общего не имеет с так называемой "фильтрацией". Это опять же только подготовка. Обработка, если угодно. И функция htmlspecialchars() ничего общего с этим не имеет. Вчитайтесь в её название. html.... Где тут что-либо про SQL? Для SQL запросов применяются совершенно другие методы обработки. Это либо mysql_real_escape_string(), если используется устаревшая mysql, либо её аналог mysqli_real_escape_string() из пришедшей ей на замену mysqli, либо подготовленные запросы из PDO к примеру. Они выполняют иные функции, нежели "фильтрация данных". Они экранируют  потенциально опасные для SQL запросов символы, обеспечивая их безопасный транспорт в СУБД.


Можно еще целочисленные данные приводить в соответствие функцией intval() или конструкцией приведения типов (INT).


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


РЕЗЮМИРУЕМ.

1. Никогда не говорите словосочетание "фильтрация входящих данных". Эта фраза выдает в вас дилетанта.
2. Никогда не обрабатывайте текст функцией htmlspecialchars() перед внесением в базу данных.
3. Наоборот, всегда обрабатывайте ей данные, отправляемые в поток. В любом месте. 
4. Для подготовки данных к внесению в СУБД применяйте специальные для этого средства (перечислены выше)

5. Не читайте перед обедом советских газет © Булгаков.



 И я гарантирую здоровый, крепкий, младенческий сон без подскакиваний по ночам в холодном поту - как там мой сайт?? Не взломали ли часом его?

 

Николай aka twin

 

Теги: PHP | MySQL

Комментарии (15)

kdes70
20-03-2013
скажите twin а могут ли злоумышленики скачать (мой сайт)с хоста для получения исходников??? недавно наткнулся на одном из форумов там говорили о токой проблеме.
twin
20-03-2013
Скачать могут только HTML, есть специальные "сйтокачалки". PHP исходники можно скачать только если есть доступ к ФС. FTP допустим или шелл закинули. Иначе никак.
Fable92
20-03-2013
Скажите пожалуйста, а есть ли какие-то особенности при использовании ajax запросов, я имею ввиду их безопасность.
twin
20-03-2013
В основе все тоже самое. Но есть кое-какие тонкости. Об этом как-нибудь отдельно нпишу.
Fable92
20-03-2013
Спасибо, буду ждать
Иван
05-04-2013
twin:3. Наоборот, всегда обрабатывайте ей данные, отправляемые в поток. В любом месте.

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

twin:1. Никогда не говорите словосочетание "фильтрация входящих данных". Эта фраза выдает в вас дилетанта.

Есть моменты когда и на входе можно фильтрануть. htmlpurifier как раз такой пример. Так что бросок камня мимо. Есть данные, их искажать не надо, а есть и просто какая то информация, контент, который можно и без вреда изменять.
twin
06-04-2013
Ну если у вас пользователям дозволено пользоваться HTML, ради бога.Можно ссылки на ваши саты, не дай бог туда попасть даже случайно. Ведь от XSSстрадают как раз пользователи, а небеспечный хозяин ресурса и тем более недоучившийся программист.

Второе.
Не нужно путать фильтрацию с валидацией. Можно запретить, если не проходит под формат. Но не фильтровать, это  любом случае искажение.
Иван
08-04-2013
Возможность вводить html определенными группами пользователей сайта это вынужденная необходимость.
Теми же редакторами, которые создают статьи. Или на сайтах, которые нацелены где пользователи создают контент. BB кодов и прочего примитива недостаточно, а html-a они не знают. Визивиг редакторы типа ckeditor - единственный вариант, но он выдает html. Как же его потом выдавать для всех? Чтобы в html-e не было xss можно заюзать решение htmlpurifier, но не на отдаче же его использовать, нафиг такие тормоза, пусть подровняет сразу при записи.
Но ты не читаешь внимательно чужие комменты, иначе бы не писал непонятливый коммент выше, т.к. увидел бы про пурифайер и прогуглил что это такое.
Если с чем то не согласен, то окей, ответь на вопрос - как позволить пользователям добавлять на сайт хорошо оформленный контент, без неимоверных усилий для них?
На современные сайты контент же поступает не только от одного дяди владельца сайта. Только на визитках и прочей простоте.

Искажение - да, а что делать. Только валидация не пройдет. Ну вставил редактор из WORD-а в визивиг статью, что то там не так. Не сказать же юзеру - "в вашем html что то не так, иди его изучай, потом исправляй", нет, надо исправлять самому.
twin
08-04-2013
Любое решение подобного плана несет в себе массу потенциальных угроз. Этот твой хваленый пурифайер тоже до сих пор патчится. А сколько уязвимостей было найдено, не сосчитать. Кроме того, это разметка. Я готов согласится, что есть исключительные ситуаци, когда пользователю действительно нужна разметка. Но это исключния и они только подтверждают правило. В 99,9% случаев разметка - вещь для юзера совершенно излишняя, а для сайта потенциально опасная.

Особенно если хранить ее в базе и отдавать как есть. Я описал ситуацию в статье, не буду повторяться.  И в такой ситуации никакой htmlpurifier не поможет.
Иван
14-04-2013
@twin Особенно если хранить ее в базе и отдавать как есть
Хранение разметки в БД ничем не отличается от хранения ее в файлах. Ты же свои шаблоны на диске в формате html надеюсь хранишь? Modx свои шаблоны в базе хранит. Тут нет никакого скрытого смысла. Пример из статьи про поиск вкрапления в базе некорректен.
Понятие фильтрация данных - несколько большее чем то что ты называешь и устоялось.
Вот в yii, в авторитете этого популярнейшего фреймворка сомневаться - глупость, http://yiiframework.ru/doc/cookbook/ru/form.validation.fiters учтена возможность предобработки данных перед сохранением ;). Это то же называют "фильтры" и фильтрацией данных. Иди в ногу со временем, кто не идет вперед, того жизнь двигает назад.
twin
20-04-2013
Хранение разметки в БД ничем не отличается от хранения ее в файлах. Ты же свои шаблоны на диске в формате html надеюсь хранишь? Позвольте, а причем тут шаблоны? Речь шла о данных, полученных от пользователей.

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

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

Использование собственных фильтров в правилах валидации

Я уже говорил, не путай валидацию с обработкой данных. Да, можно написать любой фильтр, но только для валидации, а не для изменения данных. Объяснить разницу?

Валидация, это проверка. А фильтрация - искажение. Если не предусмотрено последнее, ни о какой фильтрации речи идти не может. Если есть функционал транслитерации, то это оговорено заранее. У нас тоже применяется такой функционал для преобразования текста в URL (посмотри в адресную строку). Но это не та опера, здесь такие преобразования априори оговариваются на берегу.

А всё, что написал юзер как текст, должно отображаться именно так, как он написал. Никаких потерь и никаких замен быть не должно. А потери и замены и есть фильтрация.

...учтена возможность предобработки данных перед сохранением ;). Это то же называют "фильтры" и фильтрацией данных

Продолжай называть как хочешь. Можешь называть голову задницей, они же обе круглые, не важно, что у них несколько разнится функционал. Это же так в ногу со временем.
pamparam
20-04-2013
Есть мудрая поговорка...
из двух спорящих неправ тот , кто умней ...

Хвать выяснять что да как называется в разных источниках многие моменты по разному называются и что? ...
king
29-05-2013
Приветствую!
У меня недавно взломали сайты (на хосте находятся в одной главной директории), какие-то албанские террористы хакеры.
Че они сделали - поменяли содержимое главного index.php, а в сайте на Джумла, еще и некоторые данные в конфиге.
Как они вообще смогли *.php файл достать? В .htaccess стоит защита на эти типы файлов.
В инете читал, что доступ к файлам можно получить через sql-инъекцию, тока как ума не приложу.
Не в курсе как это делается и главное как защититься?
twin
30-05-2013
Если взломали все сайты, то скорее всего увели пароли от FTP. Это с веб-безопасностью не имеет ничего общего. Антивирус проспал.

Нужно сменить пароли, но прежде найти и обезвредить вирус.
stmike
19-10-2014
Рекоменжую убрать из статьи упоминание о s~x.com. Такое упоминание может трактоваться как ссылка на порно-ресурс, и иметь как для автора, так и для всего сайта нежелательные юридические последствия.

 
Наверх