Pull to refresh

Уязвимости прозрачного проксирования, отмена похорон WebSocket, выдыхаем…

Reading time 5 min
Views 7.1K
Прочитав «Веб-сокеты временно отменяются», не смог удержаться и решил ответить.



Итак, последние новости с фронтов IT. Они шокируют.

Из-за серьезной незакрытой уязвимости в Adobe Flash от его поддержки отказались все ведущие браузеры. Да, да больше в сети не будет Flash, увы. Об этом заявили все ведущие бабушки, сидящие на скамейке в моем дворе.

Из-за серьезной незакрытой уязвимости в Internet Explorer всех версий до 9 все пользователи IE отказываются посещать Сеть. Новый кошмар для верстальщиков — больше не нужно поддерживать версии сайта для разных версий IE. Кошмар! Куда девать полученные навыки? Где есть свободное место дворника?

Из-за серьезной незакрытой уязвимости в Windows все производители браузеров отказываются поддерживать эту платформу. «Да, да, мы переходим на ReactOS», в эксклюзивном интервью подтвердил ведущий разработчик ведущего браузера ведущей фирмы на ведомом рынке.

Наконец, апофеозом стало заявления руководителя разработки зимних шин в компании Мышлен. «Мы проанализировали 1829783 аварий, произошедших с автомобилями, на которых были установлены наши шины. И пришли к выводу, что на всех из них были круглые колеса. Так как безопасность вождения — это наше все, то мы решили отказаться от круглых колес и переходим на квадратные. „

Ну пошутили и хватит. Давайте попробуем разобраться.

Раньше всего, статья Adam Barth озаглавлена “Transparent Proxies: Threat or Menace?». То есть, автор исследует не протокол WebSocket, а «прозрачное проксирование».

Что это такое? Все просто — если клиент указал прокси явно, то это явный прокси. А если любой запрос браузера (допустим, в каком-то отеле) незаметно перехватывается специальным прокси для фильтрации, то это и есть «прозрачный» прокси.

Проблема (по мнению автора) заключается в следующем. «Прозрачный» прокси получил HTTP-запрос. Поскольку прокси «прозрачен», он перехватывает запрос, направленный от клиента на определенный IP-адрес (сервера). При этом в самом HTTP-запросе может быть еще и указан Host. Вроде с точки зрения логики прокси должен направить запрос туда, куда он и шел — то есть на исходный IP. Однако, по утверждению авторов некоторые прокси направят HTTP-запрос на IP-адрес, который соответствует хосту в заголовке Host запроса.

Мы пока не будем обсуждать это решение с точки зрения «правильности». Предположим, что некоторые прозрачные прокси действительно перенаправят запрос на хост в заголовке Host. Что из этого следует?

Автор далее ссылается на еще один документ.

Предположим, что зловредный сайт загрузил в браузер Flash-приложение, которое получило разрешение на использование raw sockets, то есть, попросту говоря, флеш-приложение может использовать TCP/IP соединение с сервером, с которого было загружено. Может прозрачный прокси отличить такое соединение от браузерного? Не может. Если флеш-приложение сформирует и направит корректный HTTP-запрос на сервер через TCP, то прозрачный прокси решит, что этот запрос отправляет браузер. Зловредное флеш-приложение в свой зловредный запрос вставит Host, который укажет на зловредный хост.

И теперь, если прокси настолько глуп, что пойдет получать ответ к (зловредному) хосту в поле Host, то с этого сервера ему подсунут что угодно, причем прокси будет считать, что ответил ему исходный (хороший) хост (на IP-адрес которого был изначально направлен запрос).

Получаем две проблемы:

1. зловредное флеш-приложение теперь может обращаться к любому веб-серверу, а не только к тому, с которого было загружено;

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

Итак, проблема компроментации кэша прозрачного прокси и нарушения флеш-приложением SOP возникает, если прозрачный прокси перенаправляет запрос к хосту в заголовке Host (вместо использования IP-адреса, на который был отправлен запрос).

Причем тут Лужков WebSocket? Не при чем. Идем дальше. Заглянем в энциклопедию юных сурков RFC. Нас будет интересовать RFC 1919, который определяет прозрачное проксирование. Читаем:

4.2.3 DNS requirements

In transparent proxy configurations, client systems MUST be
able to resolve server names belonging to remote networks. This
is critical since the proxy will determine the target server
from the destination IP address of the packets arriving from
the client.



То есть стандарт однозначно утверждает, что надо брать IP адрес запроса, а не из поля Host.

Опять, вроде бы, WebSocket не виноват. Окей, возвращаемся к исходной статье автора.

Авторы провели эксперимент. Они раздавали людям рекламный банер, который пытался провернуть подобную схему: отправить HTTP-запрос с «другим» Host. Использовался как флэш, так и Java-приложение. Эксперимент показал, что 2.2% (803 из 36305) запросов использовавших «зловредный» Flash и 3.6% (1212 из 33820) запросов использовавших «зловредный» Java-класс были перенаправлены на Host в заголовке HTTP, а не на IP-адрес.

Далее, авторы пытаются «обмануть» прокси с использованием протокола WebSocket. Если прозрачный прокси ничего не знает про WebSocket, то клиент может после WebSocket handshake отправить в TCP сообщение вида:

GET /sensitive-document HTTP/1.1
Host: victim.com


Поскольку несчастный прокси ничего не знает про WebSocket, он решит, что это очередной HTTP запрос. Причем он «пойдет» на victim.com и передаст его туда. Эксперимент авторов показал, что так поступили 2.8% прокси (1376 из 49218). Далее, эксперимент по сути повторился.

Итак, утверждение, что WebSocket небезопасен — неверно.

Нарушение безопасности возникают из-за того, что прозрачные прокси не знают WebSocket и нарушают RFC 1919.

Авторы исследования предлагают свое решение: использовать HTTP команду CONNECT для WebSocket. Их эксперимент показал, что _все_ прозрачные прокси «хорошо» отрабатывают CONNECT. Они считают, что внутри будут HTTPS данные и не пытаются их разбирать. Запросы идут на исходный IP.

Подведем итог.

Примерно 3% прозрачных прокси рутят HTTP запросы на IP-адреса хоста, указанный в поле Host заголовка запроса. Это нарушение стандарта RFC 1919. Рутить надо на исходный IP-адрес, на который и был отправлен запрос.

Такое поведение позволяет зловредному Flash-приложению, Java-апплету или скрипту JavaScript обращаться к любым сайтам (нарушение принципа Same Origin Policy) и компроментировать кэш этих прокси.

Зловредный скрипт JavaScript может навредить только в том случае, если браузер поддерживает WebSockets. Flash-приложение и Java-апплет не нуждаются в поддержке WebSockets браузером, чтобы вредить.

Переход на команду CONNECT в handshake WebSocket (с некоторыми доработками) позволит «закрыть дыру» в случае WebSocket...

… НО ИСПОЛЬЗОВАНИЕ ВРЕДОНОСНЫХ FLASH И JAVA ПРИЛОЖЕНИЙ ДЛЯ НАРУШЕНИЯ SOP И КОМПРОМЕНТАЦИИ КЭША ПРОКСИ ОСТАЕТСЯ ВОЗМОЖНЫМ ДО ТЕХ ПОР, ПОКА ПРОЗРАЧНЫЕ ПРОКСИ НАРУШАЮТ RCF 1919.

Картинка для отвлечения внимания.

image

PS

Забыл добавить. Разработчикам Оперы и FireFox надо саечку за испуг понимать, что следование безопасности должно быть системным, то есть последовательным.

Если проблема прозрачных прокси их так беспокоит, то следует запретить и Flash, и Java.

А так это выглядит как дешевый PR-трюк:

«Посмотрите мы заботимся о безопасности. Мы оставили дырявый Flash в нашем браузере, но зато мы отключили WebSocket и теперь Вы — в безопасности.»

PSS

Немного подправил. Надеюсь стало еще ясней…

Tags:
Hubs:
+96
Comments 26
Comments Comments 26

Articles