Pull to refresh

Comments 51

Здесь есть ещё один неприятный момент.
Встречался в Битриксе, но всплыть может ещё где-нибудь.
Условия:
— Веб-сервер отвечает на любой хост одним сайтом
— Относительные URL на сайте приводятся к полным URL с включением хоста
— Результатирующая страница кешируется
— Есть ещё какие-нибудь домены, ссылающиеся на наш IP

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

P.S. Слава Богу нигде не использую :)
Их не просто так назвали переменными.
А зачем парня заминусовали? Человек не постеснялся сказать, что чего-то не знал — так это же хорошо. Такие вещи нужно наоборот поощрять.
Никто опытным не рождается. Я как раз для таких людей и писал заметку.
Решение проблемы для Nginx есть, а с Apache как быть?
А с апачем это не прокатит, по-моему.
По крайней мере сейчас попробовал на локалхосте — Apache 2.2.22, не прокатывает.
Если запрос
GET http://www.site.lo/hosttest.php
Host: xxx
То SERVER_NAME правильный, а HTTP_HOST'а вообще нет.
Все логично. Если первая строка без указания протокола, то последующие заголовки не будут учтены. Соответственно, HTTP_HOST будет пустой.
Попробуйте так:
GET http://www.site.lo/hosttest.php HTTP/1.1
Host: xxx
В самой заметке есть же ссылка по Apache. В частности, должно быть UseCanonicalName Off.
А, сорри, я почему-то понял пример так, что надо как раз без протокола отправлять запрос.
Да, с указанием протокола действительно HTTP_HOST меняется… Но SERVER_NAME в апаче, правда, остаётся правильный, а всякие **внобитриксы, кстати, используют SERVER_NAME, а не HTTP_HOST, насколько я помню.
Блин. А вот MediaWiki, между прочим, уязвима, в том числе её последние версии. Она сначала проверяет HTTP_HOST, и только потом SERVER_NAME (ну т.е., уязвима, если в конфиге гвоздями имя сервера не забить).
Похоже зашлю в геррит патчик, чтобы она хотя бы на SERVER_NAME сначала смотрела — он явно покорректней будет…
лучше пусть на host смотрит :) А то, как показано выше, NgX за server_name считает тот хост, что первым указан в этой директиве, а не тот, куда пришёл запрос :(
Довольно интересно.
Я так понимаю что если у меня в nginx перечислены все возможные server_name и default_server ведет на страничку 404 то все нормально?
Не совсем. В статье есть пример с таким вот запросом через telnet
GET http://site3.dev/phpinfo.php HTTP/1.1
Если имя сервера передано в первой строке запроса, то в дальше оно может быть переопределено. Host:~%#$^&*()<>?@\!."'{}[]=+|
Можно ограничиться защитой только на стороне Nginx, но для этого стоит явно определить переменную HTTP_HOST: fastcgi_param HTTP_HOST $host;
Если сервер отвечает на любой хост своим сайтом, то это кроме всего прочего уязвимость — DNS Rebinding.
Если хост не сматчился — нужно отдавать страницу, что-то типа «This host is not found on our server», пример.
В общем-то как мне кажется это не уязвимость, а типичный мисконфигурейшин.
Ну дефолтный виртхост должен всегда отдавать или что-то типа 403 или редиректа…
Любой мисконфигурейшин может стать уязвимостью и многие (не все) уязвимости есть следствие мисконфигурейшина.
В HTTP_HOST кроме подмены самого хоста можно передать непредусмотренную последовательность символов.
Я так и не понял, где уязвимость дальше чем «нам отдадут не тот виртуальный хост».
Автор, сдается мне, немного не в ту сторону ушел.
Уязвимость можно реализовать подменой, например, HTTP_REFERER или HTTP_USER_AGENT, при условии что они где-то на стороне сервера вообще как-то обрабатываются.
К сожалению, именно HTTP_HOST часто оставляют без валидации. Хотя все эти переменные начинаются с HTTP_, что как бы намекает. А вот с SERVER_NAME менее очевидно.
Автор просто не раскрыл тему до конца. Точнее как-то двумя строчками ограничился в разделе «уязвимости».
В общем, суть в том, что если разработчик просто подставляет данные, например, из переменной $_SERVER['HTTP_HOST'], без какой-либо фильтрации при работе с базой — то мы можем провести sqli. Похожее задание было на phdays quals, краткий врайтап по ссылке.

Предложенный способ защиты на php является костылём и говорит о том, что программист не до конца понимает работу HTTP и работу виртуальных хостов. Как уже верно подметили, нужно просто четко и явно матчить HOST, а все, что не наше — отдавать 404, 403 или редирект.
В общем, суть в том, что если разработчик просто подставляет данные, например, из переменной $_SERVER['HTTP_HOST'], без какой-либо фильтрации при работе с базой — то мы можем провести sqli.

Да сколько же раз говорить, что при работе с базой все данные нужно трактовать одинаково (кроме тех, которые мы порождаем сами внутри security boundary)? И все эти защиты на уровне конфигов веб-сервера к этому никакого отношения не имеют.
Да я абсолютно согласен :)
Но не сказал бы, что не имеют. Порой на плечи админов ложится лишняя нагрузка, из-за программистов, которые не уделяют нужное внимание security (проблема многих проектов). Как, порой, и наоборот, когда в директории кладут пустые index.html, если по каким-то причинам не получается отключить индексирование (переопределение в .htaccess запрещено) или вообще используется nginx и до админа не достучаться.
Порой на плечи админов ложится лишняя нагрузка, из-за программистов, которые не уделяют нужное внимание security (проблема многих проектов).

Лучше бейте программистов. Это полезнее.

Костыли в безопасности — опасная вещь.
вот вот. должна быть единая идеология — архитектура по управлению данными, внезависимости откуда ты их взял. тут помоеж т ORM
… и ORM тут тоже не при чем совершенно. То, о чем вы говорите — задача DAL в произвольном виде, вне зависимости от используемого шаблона.
Совершенно верно. Добавлю, что я не ставил себе цели описать все возможные векторы атак, а лишь пытался дать предостережение тем программистам и системным администраторам, которые не придавали этим переменным должного внимания.
Как показывает практика, это не такая уж и редкость.
Все, что начинается с HTTP_* можно «подделать». Но это не подделка, это просто данные полученные от клиента.
>Получение доступа к приватным данным
SQL-инъекции

таки где демо? чем эта переменная круче REFERRER например который тоже могут теоретически не фильтровать? 0day?
Фильтровать нужно только если используется. Ничем не круче REFERRER. Я к сожалению, сейчас не найду, но на том же Гитхабе видел подключение конфигурационных файлов по полученному имени хоста. Потенциально это дыра.
То есть с одной стороны программисты не фильтруют, т.к. это должно быть сконфигурировано админами, а админы оставляют на откуп программистам. Возьмите любой шаред хостинг и почти наверняка получится повторить приведенные в посте примеры.
Может поделитесь способом подменять REFERRER? Есть просто проблема, флеш баннеры в упор не хотят передавать REFERRER.
с помощью искусственного запроса, можно и реферрер подделать и IP, и прокси
подделать и IP

ну с 'HTTP_X_FORWARDED_FOR' понятно все, а вот как REMOTE_ADDR искусственным запросом подделать очень даже интересно послушать
REMOTE_ADDR http заголовками не подделаешь, но бывают совсем отмороженные админы, которые настраивают сервер так, что при отправке заголовка X-Forwarded-For: fail_IP воспринимают fail_IP как настоящий. Сам такое видел.
В наказание таким админам и их клиентам как раз и появился вот этот github.com/marson/XForwardedForHeader аддон.
Еще есть случаи когда в закрытой части сайта делают редирект на страницу входа,
а в теле все равно страница, например админки,
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Если скрипт должен собирать статистику в БД, а программист не ожидает подвоха, то вполне возможно. Понятно, что данные перед записью в БД должны фильтроваться в любом случае.
Еще в самом первом комментарии прекрасный пример XSS — нарочно и не придумаешь.
UFO just landed and posted this here
Ну а пример «Получение доступа к приватным данным»?
А в чем суть нолика в слове HOST -> H0ST?
Может опечатка? А где вы увидели нолик?
Почти везде. В некоторых шрифтах особенно заметно:



Причем, в коде так же. Я думал, может какое-то хитрое вуду на этом замешано :)
Английская O находится аккурат под 0, пару раз сам так случайно опечатывался
Наверное единственная опечатка без потери смысла/орфографии :)
Если бы человек опечатывался, то был бы не 0, а ")", потому что это слово набирается с шифтом.
В данном случае 0 набрано сознательно. Быть может для защиты от скрипт-кидди, но это явно слишком просто.
Прямо целая теория заговора на моих глазах родилась :)
Где вы там все же нули видите, я не пойму?
Нет там никаких нулей у меня!
Действительно нет. Но вы же не будете разрушать нашу красивую, загадочную теорию заговора? Впишите нули в текст! :)
пардон, а чем HTTP_HOST безопаснее любых других суперглобалов? экранировать все в любом случае!
Данный баг был например в CMS е107. Там в шаблон включалась переменная основаная на HTTP_HOST, для вставки картинок на сайте. Далее производилась замена псевдопеременных на данные используя preg_replace с модификатором /e
Как итог, выполнение произвольного кода, который мог присутствовать в HTTP_HOST ввиде {phpinfo();}, и решением была замена preg_replace на preg_replace_callback, но использование HTTP_HOST так никто и не переписал.
Sign up to leave a comment.

Articles