Как стать автором
Обновить

Комментарии 60

Интересное решение для ситуации, когда требуется хостить подозрительные сайты.
В качестве альтернативы можно попробовать Nemesida WAF Free — полностью бесплатный, представлен в виде динамического модуля Nginx, устанавливается и обновляется из репозитория, не требует компиляции, подключается за несколько минут к уже установленному Nginx (начиная с версии 1.12). waf.pentestit.ru/about/2511
Используется-ли данный модуль на продакшене? Как долго? При какой нагрузке?
Да, используется, нагрузка на продакшене мала, но были проведены тесты/бенчи при нагрузке через ab.
Подробности в след статье, ок?
Будем ждать!
Хм, для фряхи в nginx-devel модуль есть, в стабильной пока нет. Пойду поставлю devel, очень уж хочется потестировать модуль:)
Вот только хотел статью опубликовать про naxsi!
Ну что ж, спасибо, информация нужна, а кто не успел, тот опоздал)
$SQL и $XSS — для магазина по продаже подгузников это сработает. Для сайта типа Хабра — по очевидным причинам — нет.
$RFI — ну, тут, скорее всего, можно сделать достаточно надёжный набор правил.
$TRAVERSAL — здесь тоже 100% попадание — модуль идеально подходит для этой задачи. Главное поисковики не забанить
CSRF — проверка реферера, с теми же дырами, что и обычно.

Так что я бы всё-таки подчеркнул разницу между «поможет защитить» от «защищает». Особенно на «важном для бизнеса участке».
Да, это не серебряная пуля, но при грамотной настройке может помочь.

$SQL и $XSS категории вполне можно применить для хабра, указав в каких полях может быть sql и код. На то и нужны вайтлисты с возможностью разбивки по зонам.
Я думаю, что Вы ошибаетесь. Можно захаркодить правила наверное для 90% случаев, просто нужен опыт в этом деле хороший.
Можно.
Но решение ведь явно из разряда «поставил и забыл».
А при наличии таких ресурсов, как время и опыт, я бы всё-таки потратил их на написание безопасной версии сайта, а не на паллиатив.
Так что модуль явно для «ситуации, когда требуется хостить подозрительные сайты» которые не жалко, а времени заниматься ими нету.
Да, согласен, время идёт и много нового. Но, настройкой модуля и разработкой сайта всё таки могут и _должны_ заниматься разные люди. Поэтому настроить и обновлять модуль не является большой проблемой через репозиторий. Даже считаю, что уже необходимо такой создать, где люди могли бы совместными усилиями составлять и дополнять правила в конфиге/конфигах под разные ситуации.
Ой, вот уж чему-чему, а «коллективному разуму» я безопасность своего сайта тем более не доверю. У семи нянек — дитя без глазу.
А честные посетители получают Forbidden за смайлик и пример SQL запроса в комментарии.
По описанию сладко… Нужно пощупать ручками.
Спасибо!
Я давно наблюдаю появившийся nginx-naxsi в менеджере пакетов Synaptic, чуток описание прочитал и решил отложить его использование на попозже когда будет время с ним разобраться и узнать получше — вот и пришло время для этого.
Такие модули заставляют девелоперов писать некачественный код, полагаясь на ВАФ. :)
Прямо таки «заставляют»?

Они бы и рады писать хорошо, но раз есть NAXSI — будут писать плохо?
Ну, здесь, мне кажется, мы говорим о гипотетических сайтах с «ужасным» legacy code.
Если говорить о новых разработках, то уж читатели-то хабра должны бы уже забыть о таких простых атаках, как
— SQL-инъекция (2 простых правила для написания безопасного кода)
— CSRF (1 правило)
— LFI/RFI/TRAVERSAL (два)
с XSS сложнее, но уж на уровне-то этого модуля тоже решение элементарное. Которое, к тому же, не будет за смайлики 403 показывать.
Могли бы вы написать эти простые правила?
Хм, да было бы интересно услышать, только если это не всем известные правила, вида CSRF: POST — изменение, GET — просмотр, ну и если это не правила по использованию тех или иных вещей в php и его конфигах, т.е. если это не привязано строго к ЯП.
Наверное так:
1.1 Строковые значения в SQL запросах экранировать (с учётом параметров текущего соединения)
1.2 Числовые значения или приводить к числу, или проверять на то, что это числа
2 Генерировать и проверять токен в формах на изменение данных, ессно формы POST
3 Тут затрудняюсь сказать что конкретно имелось в виду, но в общем не использовать в файловых функциях что попало, даже полученное из БД или файлов доступных на запись, куда вроде бы сами положили. По возможности использовать хэши (include $pages[$_GET['page']] . '.php';, где $pages['some_page'] == 'some_page', а не include $_GET['page'].'.php'; для php) или другой вариант «белого списка» имён файлов. Если невозможно — фильтровать ввод на спецсимволы вроде точек и слэшей или проверять, что реальные пути запрашиваемых файлов не выходят за отведенные им каталоги или другой вариант белого списка каталогов, причём сравнивать обязательно реальный путь, вычисленный уже осью, а не то, что пришло извне.
4 (XSS) экранировать вывод (не забывать что для HTML нужно одно экранирование, а для JS(ON) другое)
Ну это стандартно дефакто понятно все :) жду все же может раскроют «тайны» какие-либо) кстати, токен тоже не особо помогает при CSRF )
Так я ж и не писал про какие-то секретные знания. :)
Наоборот, исходил из того, что читателям хабра эти правила известны.

Можно про CSRF своими словами или ссылкой?
лучше ссылкой, я не спал уже полтора дня, поэтому словами будет тяжело :) href=«www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF) (очень много, но подробно, думаю эта ссылка вам известна скорее всего), а второе это вот это www.adambarth.com/papers/2008/barth-jackson-mitchell-b.pdf тоже разобраны способы различные, их плюсы и минусы :)
Ну, по обеим ссылкам пишут, что токен-то как раз работает, просто его забывают использовать (для формы авторизации, например).
Хм, да основная проблема состоит именно при авторизации, когда собственно и происходит генерация токена, проблемы с токеном могут вскрыться потом, например при AJAX(если не хранить один и тот же токен для всей сессии, а сбрасывать его при каждом пост запросе), плюс если почитаете ссылку вторую до конца там тоже описываются ситуации другие.
А можно, всё-таки, своими словами?
«Другие ситуации», которые я там увидел — это другие типы атак, man in the middle, например.
Но подтверждения фразе «токен тоже не особо помогает при CSRF» я там не увидел.
Ну например, приложение находится на нескольких доменах это уже значит что токен приходится хранить в куки(недостаток существенный), если у вас сессия не в БД конечно, хотя и это накладывает свой гемор, дальше как я уже указал, если сбрасывать каждый раз после post-запроса например, то это уже проблемы с ajax и прочими подобными вещами. Скомпрометировать те же куки и узнать токен ведь проще(неважно как, сейчас не рассматриваем как украсть куки) на стороне клиента, чем как-то на стороне сервера его подделать? С другой стороны можно было бы анализировать реферер но и он может быть подделан(в ссылках описано), поэтому ни то ни то не спасает полностью, и приходится выбирать в зависимости от нужд. попытался описать кратко, не ввязываясь в особую демагогию :)
Нет-нет, токен в куках — это не «недостаток», это просто фейл.
Куки в принципе не могут защитить от CSRF, исходя из самой природы этой атаки: зачем красть куку, если браузер сам её отправит? :)

Не вижу, кстати, причины, по которой токен в коде формы не будет работать на мультидоменной конфигурации. Чем токен отличается от любой другой сессионной переменной?
Если у нас есть требующее сквозной авторизации приложение, работающее на нескольких доменах, то сессия по определению должна работать на них на всех.
Я же описал выше, что сессию придется кидать не в «файлы», а как минимум в БД, что естественно накладывает и свои ограничения, специфические для реализации сессии через БД(так что ваш вопрос звучит немного непонятно), особенно когда несколько серверов, вообщем это долгая тема. По поводу куки кстати, в Yii так сделано :) там токен генерируется 1 раз и ставится в куки, потом из них забирается если что, решение сомнительное но все же :)
Да какая разница, куда «кидать» сессию?
К защите от CSRF это не имеет отношения.
Сессия может прекрасно жить и в файлах, если «несколько доменов»находятся на одном физическом сервере. Может «кидаться» в мемкеш даже если домен только один. может в базу. Но к теме вопроса это не имеет ни малейшего отношения.

В общем, чтобы определиться.
1. Сессия тут вообще не при чём. Она у нас уже есть, и как она реализована — нам не важно.
2. В куках токен хранить не имеет смысла:
— если использовать его по прямому назначению — проверяя его наличие при обработке формы — то для защиты от CSRF это не поможет.
— просто класть в куки, «а потом забирать, если что» так же бессмысленно: злоумышленник преспокойно получит токен себе и впишет его в форму. Смысл имееет только пара «токен в сессии — токен в коде формы»

Так я до сих пор и не увидел примера ситуации, в которой сохраняемый одновременно и в сессии, и в форме токен «не особо помогает при CSRF.»

Блин, я вам в предыдущих сообщениях все подробно расписывал и ссылки приводил, а у вас на любой мой ответ только одно «не вижу доводов», ну круто че. Вообщем лучше закрыть тему, а то это будут взаимные притензии и оскорбления еще не дай бог :) каждый при своем :)
Ясно. По остальным пунктам возразить нечего.
Вот и славненько.
ну остальные пункты почти «аксиомы» базовой безопасности приложения, если кто-то не соблюдает их, то сам виноват.
По пунктам моего комментария выше.
В нём объясняется, почему твои «подробно расписанные сообщения» не имеют никакого отношения к вопросу, который был тебе задан.

Возразить на эти объяснения тебе нечего.
Что, с одной стороны жаль — я ожидал большей адекватности от собеседника — но с другой сильно облегчает мою задачу: мне больше не нужно тратить своё время.
уж читатели-то хабра должны бы уже забыть о таких простых атаках, как

Стандартно, но, наверное, подавляющая часть сайтов с уязвимостями эти правила не соблюдает. Тут не до тайн :)
Мда, видимо, правила всё-таки не настолько очевидные, если для SQL совсем забыты идентификаторы и ключевые слова :)
RFI/LFI — remote/local file execution, directory traversal — переход на уровень выше. Чтение и вывод файлов, в общем.
Мне кажется, что правила для работы с файлами могут быть куда проще, для этого даже белый список не нужен.
Я вообще всегда стараюсь упрощать наборы правил, а то длинные соблюдать сложно :)

Что интересно — правила разработки отличаются от правил фильтрации. Первые одновременно и проще, и надёжнее. Именно этим фактом вызвано моё скептическое отношение к таким файрволлам.
Если, скажем, фильтратору важно знать, что в переданном запросе есть точки, то он даже невинные зарубит, а обращение, скажем, к абсолютному пути прекрасно пропустит — там точек нету ведь! :)
А разработчик может просто выделить в переданном параметре имя файла, каталог сгенерировать самому и проверить получившийся путь на читаемость.
Про идентификаторы и ключевые слова не понял. Когда в урлах или полях поста передаются названия таблиц и/или полей, а то и UPDATE/INSERT/...?
Да, верно. Только речь не только об урлах, а о динамике в запросах вообще.
И в качестве примера ключевого слова я бы привёл скорее такие, как OR или DESC.
А про RFI/LFI/Traversal я и написал, что или точный белый список файлов, или белый список каталогов по real path. С правилами сложно всё предусмотреть, по-моему, чтобы сделать универсальный фильтр, который из проекта в проект таскать.

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

Для случаев, когда приложение занимается именно просмотром физических каталогов по запросам пользователя, подойдёт описанное выше решение-аналог open_basedir.
Я больше про довольно удобный вариант когда у каждого юзера своя «домашняя» папка.
А пользовательские-то файлы здесь при чём? Мы же, вроде, говорили о защите файлов приложения/сервера?
Я не очень понял сценарий атаки с пользовательской папкой.
Типа пользователькие файлы аплоадятся к нему в паку, а потом доступ к ним по урлу. Вроде example.com/image.php?path=user/album/photo.jpg

В таких случаях беру real path от UPLOAD_DIR . $_GET['path'] и смотрю чтобы не вышел за UPLOAD_DIR Если не смотреть, то можно /etc/passwd получить вместо фотки :)
Речь о правилах разработки, а не фильтрации, если что :)

SQL: данные в запрос передавать только через плейсхолдеры. Идентификаторы и ключевые слова — только фильтруя по белому списку, своему для каждого запроса.

CSRF: привязанные к сессии токен в каждой POST форме.

Чтение файлов: при передаче через пользователя имени файла, всегда передавать только его имя, без пути, и соответствующим образом валидировать. (basename в простейшем варианте). Путь же строить всегда самому, внутри приложения.

XSS — htmlspecialchars принудительно внутри шаблонизатора для всех переменных, кроме, опять же, специально помеченных в белом списке.

Такие очевидные правила, как «ни одна переменная не выводится мимо шаблонизатора» или «никакое действие, меняющее состояние сервера, не выполняется методом GET » я не выделяю отдельно, хотя, возможно, стоило бы.
ну вообщем вы перечислили правила «де факто», которые 90 % норм. разработчиков знают :) ну и на этом спасибо)
А как показывает практика разработчики 90% сайтов с уязвимостями… 90% сайтов делают 10% разработчиков, которые эти факты не знают? :)
Повторение — мать учения, поэтому спасибо)
Пользователи gentoo могут проголосовать за включение naxsi в ебилд nginx тут.
Есть ли уже готовый пример сайта? Хотелось бы посмотреть ни сиё чудо.
И как же должен со стороны выглядеть сайт, прикрытый web application firewall? Чем отличаться от остальных?
скорее всего уважаемый Asperka хотел увидеть работающий конфиг для «реального» сайта.
Вот наставят такого, еще всяких сухосинов, а что толку? Все равно если приложение подвержено, то найдется способ провести атаку.
Сухосин не плохо фильтрует левые запросы. Зачем их обрабатывать даже если атака не пройдет? — это лишняя нагрузка. Тут то же самое, но уже на более низком уровне (на уровне веб сервера) — фильтр левых запросов, — лишним не будет при правильной настройке.
Чтобы такой фильтр («ненужных» запросов) был эффективным, к нему нужна ещё дополнительная банилка, скажем, на час.
Нам баннилка не нужна, т.е. нам хватает того, что левые запросы отсекаются просто, если вы считаете, что это эффективно или в вашем случае это необходимо, можно и баннилку прикрутить — это не проблема. Я просто возразил на то, что от подобных фильтров нет толку. Если
у вас сайт посещает 200 человек в сутки, толку, конечно, мало. Если же у вас проект работает под нагрузкой, дополнительный фильтр «левака» совсем не помешает. То есть, я рассматриваю это именно как фильтр, а не как защиту на которую нужно уповать, — понятное дело сухосин не спасет от нормальных хакеров.
:)
Как раз о снижении нагрузки и идёт речь.
Вы забываете, что здесь используется чёрный список.
То есть, он по определению не может охватить все «паразитные» запросы.
При этом мы можем предположить, что если с определённого IP пришёл запрос на /etc/passwd, то в течение ближайшего (условно) часа от него вряд ли можно ожидать покупок, и с чистой совестью можно банить.
А отсекать 1 запрос по известному системе паттерну и пропускать 99 столь же «полезных», но валидных с точки зрения файрволла — смысла немного.
Впрочем, вы правы. Если у вас посещаемость не 200 человек в сутки, хакерская активность не слишком заметна на фоне обычного трафика.
>При этом мы можем предположить, что если с определённого IP пришёл запрос на /etc/passwd, то в течение ближайшего (условно) часа от него вряд ли можно ожидать покупок, и с чистой совестью можно банить.

Как же бесит, когда из-под провайдерского или рабочего NAT заходишь, а там что-то вроде «Hacker, your are catched. he-he»
Кто-нибудь пробовал использовать предложенный в naxsi-0.46-1 lerning mode?
code.google.com/p/naxsi/wiki/LearningMode0_46 — в комментах жалуются на то, что после формирования база остается пустой. Хотя эксепшны в логах nginx'а есть.
Блин. Что-то я вот тоже попробовал эту хрень — хотел поставить на сервер това'ища, который наплодил у себя портальчиков на вордпрессе и которые ему раз в неделю где-то ломают. Хотел сначала отрубить все правила и оставить только одно — запрет загрузки *.php.
Убрал вообще все MainRule, кроме одного, убрал все CheckRule, кроме одного, соответствующего этому MainRule.
А оно всё равно блокирует многие запросы. Причём вообще не понятно, по какому принципу:

2013/06/27 18:43:44 [error] 19870#0: *345 NAXSI_FMT: ip=111.253.0.43&server=XXXXXXXX.ru&uri=/wp-login.php&total_processed=30064771079&total_blocked=22333829940, client: 111.253.0.43, server: XXXXXXXX.ru, request: «POST /wp-login.php HTTP/1.0», host: «XXXXXXXX.ru», referrer: «XXXXXXXX.ru/wp-login.php»
2013/06/27 18:43:44 [error] 19870#0: *348 NAXSI_FMT: ip=94.127.70.77&server=XXXXXXXX.ru&uri=/wp-cron.php&total_processed=8589934594&total_blocked=12025908428, client: 94.127.70.77, server: XXXXXXXX.ru, request: «POST /wp-cron.php?doing_wp_cron=1372344224 HTTP/1.0», host: «XXXXXXXX.ru»
2013/06/27 18:43:45 [error] 19870#0: *353 NAXSI_FMT: ip=24.139.92.197&server=XXXXXXXX.ru&uri=/wp-login.php&total_processed=34359738376&total_blocked=22333829940, client: 24.139.92.197, server: XXXXXXXX.ru, request: «POST /wp-login.php HTTP/1.0», host: «XXXXXXXX.ru», referrer: «XXXXXXXX.ru/wp-login.php»

Где здесь вообще информация о применённом правиле?..
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории