Основы безопасности веб-приложений

Б
На сайте с 19.01.2007
Offline
5
6687

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

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

Забив на все попытки third-party писателей классифицировать способы защиты веб-приложений, я решил создать собственную классификацию, состоящую из трех простых правил, которые не лишне взять на вооружение любому веб кодеру / админу. В эти три правила уложились все основные принципы безопасности веб приложений и основные способы их защиты, способные отразить львиную долю всевозможных хакерских атак. Разумеется, чтобы отразить ВСЕ хакерские атаки, требуется нечто большее чем комбинация из трех п., :) но об этом - в конце статьи.

Итак, три основных правила веб-безопасности:

Правило 1. Никогда не доверять информации, приходящей от клиента на сервер.

Любой байт, принятый сервером, может являться частью хакерской атаки.

A) Защищайте свои переменные - register_globals в PHP должен быть off. Пользуйтесь суперглобальными массивами.

B) Фильтруйте ВСЕ до единой суперглобальные переменные перед КАЖДЫМ их использованием. Фильтрация подразумевает обязательную проверку на минимальную и максимальную допустимую длину строки, на разрешенный для данной переменной строго ограниченный диапазон символов (0-9, a-z и т.д.), на наличие внедренных html тэгов и спецсимволов, если числовое значение - проверку на нижнюю и верхнюю границу допустимого диапазона. Рекомендуется написать универсальную функцию для фильтрации значений.

C) Фильтруйте весь входящий http трафик с помощью модуля mod_security (для Апача). Настройка модуля может потребовать значительного времени, но она того стоит. Благо, в Сети достаточно подробных инструкций.

D) Если в вашем веб-приложении используется закачка на сервер картинок (например, аватары для форума), то при их получении сразу сканируйте их свежеобновленным антивирусом. Картинки, кроме проверки php-шной функцией image_type_to_mime_type(), рекомендуется еще обрабатывать функцией image_copy(), перед тем как сохранить картинку на диск - для отсечения кода, который может быть прицеплен в хвост графического файла.

E) Если в вашем веб приложении есть защищенная область с доступом по логину и паролю, не поленитесь добавить к ним хорошую капчу. Это защитит ваше веб-приложение от брутфорс атаки.

Тщательное соблюдение Первого Правила позволит защититься от самых распространенных хакерских атак, таких как XSS скриптинг, SQL и SSI иньекции, PHP инклюдинг, ОС коммандинг, брутфорс и т.п.

Правило 2. Никогда не показывать клиенту ничего, кроме того, что он должен видеть.

Точнее, ничего, кроме той html страницы, которую он запросил. Все остальные детали и подробности процесса должны быть скрыты.

A) Максимально ограничьте права клиента на доступ в пределах сервера. Например, клиент может читать только этот файл только из этой директории, или читать только из этой таблицы БД, - все остальное должно быть ему запрещено.

B) В настройках Апача, во всех строках типа "Options ... Indexes Includes" удалите, от греха подальше, параметры Indexes и Includes (и не забудьте рестартануть Апач). Вы без этих двух параметров прекрасно обойдетесь, а заодно и закроете две широченные дырки для хакера.

C) Ограничьте информацию, выдаваемую в http заголовке ответа сервера, только самым необходимым минимумом. Например, стандартное поле Server ответа, содержащее полную информацию о вашем веб-сервере, не является необходимым - а хакеру оно четко указывает, дыры в каком именно ПО он может использовать для взлома.

D) Если вы используете сессии и cookie для доступа к закрытым частям сайта, то в cookie не сохраняйте ничего, кроме идентификатора сессии. Ну и генерация случайного SessionID и таймаут сессии - как не подлежащая сомнению аксиома.

E) Если вы скроете свои истинные URLы с помощью модуля mod_rewrite (Апач), то от вас не убудет, а вот хакеру это создаст значительные трудности.

F) Не слишком надейтесь защитить свою информацию от хакера с помощью md5 хэша. Хэш 4-5 символьного пароля, например, вскрывается брутфорсером PasswordsPro всего за пару часов. Лучше потратьте свои усилия на то, чтобы максимально закрыть интимные части вашего сервера от посторонних взглядов.

Хорошо внедрив Второе Правило на своем сервере, вы освободитесь от уязвимостей класса "Information Disclosure" (в переводе на русский - "по секрету всему свету").

Правило 3. Никогда не полагаться на надежность платформы, на которой работает веб-приложение.

Любое программное обеспечение, являющееся платформой для вашего веб-приложения (ОС, веб-сервер, сервер БД и т.п.), как правило имеет множество дыр, как известных, так и пока неизвестных.

A) Ставьте себе самые последние стабильные версии ПО. Устаревшие версии, как правило, имеют дыры, закрытые в более новых версиях.

B) Как можно чаще пропатчивайте свое ПО - в идеале, сразу после выхода нового патча.

C) Не жмитесь, поставьте себе хороший лицензионный антивирус, антиспайваре, файерволл и прокси. Потом сами себе спасибо скажете.

D) Если вы планируете использовать для своего веб-приложения не выделенный сервер с индивидуальными настройками, а виртуальную площадку на каком-нибудь массовом хостинге, то тогда не поленитесь тщательно выбрать хостера. Практика показывает, что бесплатный хостинг не имеет надежной сетевой защиты и легок для взлома, а многие платные хостеры грешат лентяйским отношением к техобслуживанию, что оборачивается регулярным падением их серверов и иногда даже полной потерей баз клиентов. Так что выбирайте хостера тщательно.

Соблюдение принципов Третьего Правила позволит вам решить многие проблемы безопасности. Например, установка последних патчей для ОС позволит избежать атак типа DoS или Buffer overflow, установка последних версий PHP5 закроет возможность для атак расщепленным http запросом, установка и правильная настройка файерволла закроет доступ к серверу через "левые" порты. Ну и т.д.

ИТОГО

Приведенные три правила безопасности позволяют закрыть львиную долю дыр в веб-приложении, но, конечно же, не все. Чтобы закрыть ВСЕ известные дыры, придется воспользоваться профессиональным сканером уязвимостей, из которых самые известные - XSpider, Nikto, ISS, HackerSafe. И тут уж так - либо вы воспользуетесь сканером для поиска и латания дыр в своем веб-приложении, либо хакер воспользуется этим же сканером для взлома вашего веб-приложения. Думайте сами, решайте сами.

P.S. Этот сборничек рекомендаций я писал изначально для себя, поэтому он не претендует на завершенность и полноту освещения вопроса. Кроме того, он написан для связки PHP + Apache. Поэтому, если есть конструктивные замечания и профессиональные дополнения по данному вопросу, то вэлкам.

[Удален]
#1
букозавр:
B) Фильтруйте ВСЕ до единой суперглобальные переменные перед КАЖДЫМ их использованием. Фильтрация подразумевает обязательную проверку на минимальную и максимальную допустимую длину строки, на разрешенный для данной переменной строго ограниченный диапазон символов (0-9, a-z и т.д.), на наличие внедренных html тэгов и спецсимволов, если числовое значение - проверку на нижнюю и верхнюю границу допустимого диапазона. Рекомендуется написать универсальную функцию для фильтрации значений.

1 - Фильтрация и проверка это разные вещи (и ни то ни другое не нужно)

2 - есть только 2 типа данных "числа" и всё остальное (никаких проверок на ввод HTML делать нельзя, и уж тем более фильтровать что либо, это дурной тон. Кстати WordPress этим злоупотребляет)

3 - писать универсальную функцию это вовсе бред (предложение изобретать велосипед с квадратными колёсами)

Для того чтоб полностью исключить XSS и SQL-injction нужно 3 уровня обработки полученных от юзера данных...

1 - stripslashes() в случае если включен magic_quotes_gpc (это не касается безопасности)

2 - mysql_real_escape_string() для строк и intval() для чисел при составлении MySQL запросов (этот шаг для SQL-injection)

3 - htmlspecialchars() и nl2br перед выводом в браузер. (этот для XSS)

По другим пунктам (Правило 1 A, C, D, E) в принципе согласен...

Б
На сайте с 19.01.2007
Offline
5
#2
Зингельшухер:
1 - Фильтрация и проверка это разные вещи (и ни то ни другое не нужно)
2 - есть только 2 типа данных "числа" и всё остальное (никаких проверок на ввод HTML делать нельзя, и уж тем более фильтровать что либо, это дурной тон. Кстати WordPress этим злоупотребляет)
3 - писать универсальную функцию это вовсе бред (предложение изобретать велосипед с квадратными колёсами)

Для того чтоб полностью исключить XSS и SQL-injction нужно 3 уровня обработки полученных от юзера данных...
1 - stripslashes() в случае если включен magic_quotes_gpc (это не касается безопасности)
2 - mysql_real_escape_string() для строк и intval() для чисел при составлении MySQL запросов (этот шаг для SQL-injection)
3 - htmlspecialchars() и nl2br перед выводом в браузер. (этот для XSS)

По другим пунктам (Правило 1 A, C, D, E) в принципе согласен...

"Хороший тон", "дурной тон" - факторы, высосанные из пальца. Можно руководствоваться ими на приеме у королевы Великобритании, но не при разработке системы безопасности :)

Фильтровать (проверять) все данные на входе необходимо, чтобы обеспечить защиту кода приложения.

В принципе, тут есть два варианта:

1) принимать входящие данные как есть, но при разработке кода приложения следить, чтобы в коде не осталось ни одной лазейки для запуска злонамеренного скрипта. Ни функций типа eval(), ни необъявленных явно переменных, etc. Уследить за всеми тонкостями исполнения кода - задача практически нереальная.

2) Проверять все данные на входе, при этом можно не беспокоиться о коде приложения - все данные, которые он будет обрабатывать, будут уже безопасны.

[Удален]
#3
букозавр:
будут уже безопасны.

Опасных данных не существует, это миф !!!

Опасность представляют не грамотные программисты которые пихают эти данные куда попало не конвертируя их в необходимый формат (для MySQL это mysql_real_escape_string для HTML это htmlspecialchars и.т.д.)

dkameleon
На сайте с 09.12.2005
Offline
386
#4
Зингельшухер:
Для того чтоб полностью исключить XSS и SQL-injction нужно 3 уровня обработки полученных от юзера данных...
1 - stripslashes() в случае если включен magic_quotes_gpc (это не касается безопасности)
2 - mysql_real_escape_string() для строк и intval() для чисел при составлении MySQL запросов (этот шаг для SQL-injection)
3 - htmlspecialchars() и nl2br перед выводом в браузер. (этот для XSS)

Полностью поддерживаю :)

ПС. Кроме того, разыскиваю информацию о возможности обхода mysql_real_escape_string и htmlspecialchars.

Дизайн интерьера (http://balabukha.com/)
Dreammaker
На сайте с 20.04.2006
Offline
569
#5

помню на mysql-вском сайте была инфа о уязвимости в mysql_real_escape_string. Жаль запамятовал ссылку, но найти я думаю будет не трудно.

update по просьбе трудящихся:) :

Ссылку нашёл http://lists.mysql.com/announce/364

Хотел написать краткий перевод, но решил, что не настолько доверяю своему аглицкому )

Дополнительно: Эта же проблема насколько я понимаю касается и postgres и была примерно в то же время (май 2006 года) пофиксена.

Б
На сайте с 19.01.2007
Offline
5
#6
Зингельшухер:
Опасных данных не существует, это миф !!!
Опасность представляют не грамотные программисты которые пихают эти данные куда попало не конвертируя их в необходимый формат (для MySQL это mysql_real_escape_string для HTML это htmlspecialchars и.т.д.)

Существуют, существуют :)

Поэтому я и рекомендую все входящие данные проверять (фильтровать, преобразовывать, ...) полным комплексом, с помощью тех же mysql_real_escape_string и других функций, в том числе осуществлять проверку на допустимый чарсет, длину строки и диапазон значений

[Удален]
#7
букозавр:
Поэтому я и рекомендую

Именно это и говорит о вашем уровне знаний.

(Не принимайте близко к сердцу, тут нет ничего личного, просто через годик другой сами посмотрите на этот топик и будете смеяться)

Mishael
На сайте с 08.11.2001
Offline
217
#8

переход на последнюю версию часто сопряжен с трудностями, на грани невозможности. Если крупный движок написан на PHP3 с использованием XML то на пятый не всегда быстро и просто перепишешь. Жаль.

Мой надежный веломагазин (https://veliki.com.ua/) на CMS Melbis Shop 6 (http://www.melbis.com/)
Б
На сайте с 19.01.2007
Offline
5
#9
Зингельшухер:
Именно это и говорит о вашем уровне знаний.

(Не принимайте близко к сердцу, тут нет ничего личного, просто через годик другой сами посмотрите на этот топик и будете смеяться)

Зингельшухер,

давайте по существу и конструктивно, либо идите кидать понты в другое место 🙅

[Удален]
#10
букозавр:
давайте по существу и конструктивно

Нет уж, давайте вы :)

(приведите пример "опасных" данных, иначе разговор даже не будет иметь смысла)

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий