Уже много лет пиктограмма в виде замка в адресной строке браузера применяется для обозначения защищенного соединения, означающего использование HTTPS — «упаковку» HTTP в защищенный протокол Transport Layer Security [1–3]. Когда браузер соединяется по HTTPS, есть гарантия, что пользователь посетил сайт, указанный в адресной строке, получая с него контент, отображаемый в браузере. Данная модель подходит для двусторонних клиент-серверных взаимодействий, но не для сложных систем, таких как сайты веб-почты или социальных сетей, когда сервер служит посредником между пользователями. В таких случаях пользователь вынужден верить, что сервер не меняет сообщения, не передает контент третьим сторонам и не извлекает личную информацию из сообщений. Это доверие может быть обоснованным, но убедиться в этом пользователи не могут.

Сегодня по сути такая же ситуация с вызовами, совершаемыми по технологии Web Real-Time Communications (WebRTC) — поскольку они происходят через сервер, пользователи вынуждены доверять сайту обработки вызовов. Как и с электронной почтой, во многих случаях это приемлемо — либо потому, что пользователь сам обращается к сайту, либо потому, что обращение не настолько конфиденциально, чтобы не доверить его сайту. Но бывает, что конфиденциальность все же нужна и пользователь хочет быть уверенным, что защищен от сайта-посредника. Учитывая недавние разоблачения относительно получения спецслужбами информации от онлайн-сервисов, хотелось бы создать экосистему, в которой доверять сайтам, позволяющим делать вызовы по WebRTC, уже не понадобится. Для этого в браузере потребуются механизмы безопасности, отвечающие за функции, обеспечиваемые сегодня самими сайтами: аутентификация вызовов и доступ к медиаконтенту. В первых реализациях WebRTC сайт несет ответственность и за соединение с нужным собеседником, и за проверку его личности во время конфигурирования вызова, чтобы защититься от перехвата медиаконтента. Для управления этими функциями нужна система аутентификации пользователей, не зависящая от сайта. Кроме того, сейчас сайты могут получить доступ к пользовательскому аудио и видео с помощью интерфейсов программирования WebRTC, поэтому в API необходимо будет реализовать средства ограничения такого доступа. В спецификациях WebRTC уже есть определенные механизмы для устранения рисков, и эти механизмы уже появляются в браузерах.

Борьба с угрозами в одноранговом WWW

В типичных веб-приложениях безопасность обычно обеспечивается на уровне двухточечного соединения. Пользователь заставляет браузер соединиться с сайтом https://example.com, тот начинает TLS-сеанс с сервером, объявляющим себя example.com, и с помощью предоставленных им верительных данных убеждается в том, что это соответствует действительности. TLS обеспечивает конфиденциальность и целостность данных, а браузер выполняет аутентификацию, проверяя пароль, с помощью которого специальная инстанция — провайдер идентификации — выдает утверждение о связи между открытым ключом сервера и его «личностью». Аутентифицированная сущность считается логическим источником контента и необходимого для его воспроизведения кода. То и другое принимается либо напрямую от аутентифицированной сущности, либо из уполномоченных ею источников (в случаях коллажей, сетей доставки контента и т. п.).

В WWW с поддержкой одноранговой связи, ставшей возможной благодаря WebRTC, веб-страницы, на которые заходят пользователи, служат посредниками для выхода на адресатов, с которыми те хотят связаться. Посредник, «сервис встреч», необходим для обеспечения связи реального времени невзирая на возможные перебои в работе сети, однако есть вероятность, что он свяжет вас не с тем человеком. Собственно, та же проблема есть и в других системах. К примеру, серверы электронной почты позволяют получать сообщения даже при перебоях со связью, но нет способа удостовериться, что сообщение будет доставлено именно нужному адресату.

Рис. 1. Схема сеанса связи реального времени. Алиса и Боб совершают звонок через сервис вызовов, затем обмен медиаконтентом идет напрямую между двумя конечными точками
Рис. 1. Схема сеанса связи реального времени. Алиса и Боб совершают звонок через сервис вызовов, затем обмен медиаконтентом идет напрямую между двумя конечными точками

Приложения связи реального времени обычно представляют в виде треугольника (рис. 1), две вершины которого — это Алиса и Боб, а третья — сервис вызовов (к примеру, Skype или сервер-посредник, работающий по протоколу SIP). Эта схема отвечает типичному случаю применения WebRTC, когда два пользователя сайта общаются друг с другом, а сервис вызовов обеспечивается самим сайтом с сигнализацией по HTTPS.

WebRTC с помощью кода JavaScript, предоставляемого сайтом вызовов, формирует пользовательский интерфейс и управляет потоком медиаконтента, что напоминает VoIP (рис. 2), когда имеются шлюзы для сигнализации и передачи медиаконтента, реализованные с помощью кода на JavaScript.

 

Рис. 2. Поддержка коммуникаций в реальном времен с помощью кода JavaScript
Рис. 2. Поддержка коммуникаций в реальном времен с помощью кода JavaScript

 

Браузеры Алисы и Боба, пользуясь приложением WebRTC, загружают с сервера код HTML и JavaScript. Последний, пользуясь API WebRTC, устанавливает соединения с другими участниками, а также обеспечивает получение и воспроизведение медиапотоков. Сервер также обычно выполняет функции сигнализации, помогая конечным точкам — клиентским программам Алисы и Боба — обнаружить друг друга. Есть вероятность, что в браузер пользователя от сервера будет передан вредоносный код, но в модели WebRTC браузер — это доверенный компонент, и он может с помощью средств безопасности ограничивать возможности такого кода.

Какой уровень безопасности достигается с помощью механизмов, уже присутствующих в браузерах: протокола HTTPS, используемого для сигнальных взаимодействий, и Datagram Transport Layer Security-Secure Real-Time Transport Protocol, с помощью которого защищается передача медиаданных [4, 5]? Использование HTTPS для сигнализации (со стандартной аутентификацией серверов) позволяет защититься от сетевых атак между сервером и двумя браузерами. Протокол DTLS-SRTP (Datagram Transport Layer Security-Secure Real-Time Transport Protocol) создает защищенный канал, а сайт вызовов подтверждает личность оконечных точек — браузеров.

Итак, пользуясь только встроенными в существующие браузеры механизмами, можно обеспечить довольно высокий уровень безопасности. Любые сетевые атаки, не исходящие от сайта вызовов, которому приходится доверять, бессильны — приложения WebRTC можно сравнить по защищенности с сервисами веб-чата и электронной почты. В некоторых приложениях WebRTC — это самый высокий уровень, на который можно рассчитывать, например, когда вызываемый собеседник и сервис вызовов — это одно и то же. В подобных случаях есть гарантия защищенности самих сеансов связи, но сайт вызовов может записывать или переадресовывать пользовательские сообщения или звонки.

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

Таким образом, модель угроз WebRTC требует наличия обязательных механизмов, реализующих следующие функции безопасности:

  • защиту сигнального трафика (между каждым из браузеров и сервером);
  • защиту медиатрафика между браузерами;
  • сквозную аутентификацию для общающихся конечных точек;
  • защиту медиапотоков от управляющего ими кода JavaScript.

Первые две функции обеспечиваются с помощью HTTPS и DTLS-SRTP соответственно.

Криптографическая идентификация

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

В нынешней архитектуре безопасности WebRTC используется сложное обходное решение, позволяющее избежать поиска ответа на первые два вопроса, — общая задача идентификации решается в два этапа: вначале проверяется, что удаленная сторона имеет заданную пару ключей, а затем осуществляется проверка личности их держателя. Первая задача решается посредством согласования перед началом сеанса DTLS-SRTP — браузер просто сообщает, что согласование провалилось или, в противном случае, предоставляет открытый ключ. Задача из третьего вопроса решается с помощью специального идентификационного уровня.

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

Как подобает веб-системе, конкретные идентификационные механизмы реализуются на идентификационном уровне WebRTC с помощью JavaScript — когда стороны устанавливают соединение, каждая из них загружает JavaScript-код для выдачи утверждений. Этот код проверяет личность пользователя (так, как этого требует провайдер идентификации) и генерирует утверждение (в формате, требуемом провайдером), привязывая пользовательскую личность к открытому ключу, который используется в сеансе DTLS-SRTP. Данный код служит интерфейсом между браузером и серверными механизмами сигнализации, управляемыми провайдером идентификации; при этом утверждения необходимо аутентифицировать с помощью секретного значения, определяемого провайдером.

Приложение WebRTC при сигнализации передает другой стороне утверждение с отметкой доменного имени провайдера идентификации (рис. 3). Для проверки утверждения принимающий браузер загружает код верификации (по URI в доверенном домене) и просит провайдера проверить утверждение, полученное от сигнального уровня. Это происходит дважды — для аутентификации Алисы и Боба. Браузер выполняет все взаимодействия с провайдером идентификации с помощью соединения API PeerConnection, гарантирующего, что JavaScript-код сигнализации имеет лишь ограниченный контроль над тем, какие ключи используются для DTLS и, соответственно, над тем, для какой пары ключей провайдер сгенерирует утверждение. В частности, этот код может запросить свежий ключ, но не имеет возможности использовать ключ по своему выбору или получить закрытый ключ. Это дает провайдеру идентификации гарантию, что генерируемые им утверждения не будут использоваться ни для чего, кроме WebRTC.

Рис. 3. Цикл удостоверения идентификационной информации WebRTC. Механизм сигнализации приложения WebRTC передает другой стороне утверждение с отметкой доменного имени провайдера идентификации. Принимающий браузер получает код верификации утверждения от провайдера идентификации и просит его проверить утверждение, полученное от сигнального уровня
Рис. 3. Цикл удостоверения идентификационной информации WebRTC. Механизм сигнализации приложения WebRTC передает другой стороне утверждение с отметкой доменного имени провайдера идентификации. Принимающий браузер получает код верификации утверждения от провайдера идентификации и просит его проверить утверждение, полученное от сигнального уровня

 

Абстрагирование, реализованное на идентификационном уровне WebRTC, обеспечивает ему большую гибкость — в частности, возможна поддержка широкого круга идентификационных систем, в том числе X.509, OpenID, OAuth и Persona. В принципе любой веб-сервер может выполнять роль провайдера идентификации, если разместить на нем JavaScript-код для выдачи и верификации утверждений. Благодаря этой открытости WebRTC не зависит от какой-либо модели доверия. Сама идея провайдера идентификации отвечает моделям на основе удостоверяющего центра (его роль и играет провайдер), но с таким же успехом можно реализовать код, отвечающий распределенным и другим моделям.

Важный аспект идентификаторов WebRTC — это ограничение, накладываемое форматом «пользователь@домен», где домен указывает провайдера идентификации, а «пользователь» — это личность, которую тот объявляет. Благодаря данному ограничению исключается использование в WebRTC других идентификаторов — например, доменных имен или телефонных номеров. Исключаются и сложности с определением полномочий, возникающие при использовании таких идентификаторов (например, с проверкой полномочий провайдера идентификации на подтверждение телефонного номера). Провайдер идентификации может объявлять любые личности, но лишь в пределах допустимого диапазона. Естественно, во многих случаях была бы желательной возможность использования телефонных номеров и других нестандартных идентификаторов, но тогда для их аутентификации понадобились бы отдельные механизмы — например, разрабатываемый в IETF комитетом Secure Telephone Identity Revisited.

Еще один плюс использования стандартизованных идентификаторов состоит в том, что браузеру не нужно выбирать доверенных провайдеров — он лишь раскрывает, какой провайдер поручился за определенную личность. Вследствие этого при аутентификации конечной точки возможны те же проблемы, которые уже есть в WWW. Браузер подтверждает, что человек, с которым вы общаетесь, имеет идентификатор teller@bank0famerica.com, но при этом не обязательно сможет сообщить, что домен не принадлежит Bank of America. Для защиты можно пользоваться антифишинговыми методами или, к примеру, расширенными сертификатами подлинности, но некоторые разработчики стеков WebRTC прибегают к более простому способу. Адресная книга пользователя — это по сути список личностей, которые тот сам уже проверил, и, имея возможность сверить идентификатор WebRTC с пользовательской адресной книгой, браузер может выдать идентифицирующую информацию, в достоверности которой сам пользователь уже убедился.

JavaScript-код сайта вызовов обеспечивает конфигурирование идентификационного процесса — включает или отключает объявление личности и выбирает провайдера. Последнее предотвращает подделку, поскольку, благодаря ограничению круга идентификаторов WebRTC, если сайт выберет иного провайдера, чем пользователь, будет выдано утверждение о другой личности. Возможность отказа от объявления личности — это аналог сокрытия номера звонящего в телефонии. Браузеры могут защититься от обоих видов злоупотреблений. Интеграция с адресной книгой защитит при смене провайдера идентификации, а если аутентификация происходит анонимно, то браузер может предупредить об этом пользователя.

Таким образом, в WebRTC сквозная аутентификация реализована на нескольких уровнях. Вначале на уровне DTLS-SRTP удаленная сторона ассоциируется с открытым ключом. Потом на идентификационном уровне ему ставится в соответствие идентификатор с помощью провайдера, реализованного на JavaScript. Затем пользовательский веб-интерфейс может сопоставить проверенный идентификатор с более полной информацией из адресной книги пользователя.

Локальные средства контроля доступа

Главная функция сайта, предоставляющего приложение WebRTC, — это организация виртуальной встречи. Когда Алиса хочет позвонить Бобу, то сайт в режиме реального времени определяет, как того найти, причем идентификационный уровень не позволяет соединить Алису с кем-то другим. Уровень проверки защищает Алису и Боба от атакующих в сети, от пассивной прослушки и от активных атак переадресации, осуществляемых сайтом. Но при использовании WebRTC угроза может быть в самом браузере — в коде JavaScript, поступившем от того же сервера, от которого защищает идентификационный уровень.

Для работы приложению WebRTC нужно, чтобы JavaScript-код с сервера сигнализации мог получать медиапотоки от устройств ввода и из сети и соединять их с механизмами воспроизведения и передачи. Благодаря использованию для этого JavaScript, обеспечивается гибкость WebRTC, но и создается потенциальная возможность получения тем же кодом личных медиаданных (видео с камеры или звука с микрофона либо модификации голоса или изображения пользователя). У подобных функций могут быть легитимные применения — например, сервисы звонков могут предлагать возможность записи в самом приложении WebRTC, а функции обработки видео в JavaScript можно использовать для вставки фоновых изображений или для формирования полиэкрана в видеоконференциях. Но во всех этих случаях пользователю придется доверять сайту вызовов, и нет гарантий того, что единственная сторона с доступом к медиаданным — это и есть аутентифицированный собеседник.

А если все же требуется предоставить такую гарантию? Сегодня имеется проект соответствующего API, обеспечивающего возможность отказа сайту в доступе к медиаданным — сайт, как обычно, запрашивает доступ, но добавляет к запросу специальное поле. По сути, вместо «Могу ли я с вашего разрешения получить доступ к камере?» он спрашивает: «Могу ли я с вашего разрешения отправить изображение с камеры пользователю bob@example.com?» Браузер запрашивает соответствующее разрешение, указывая конкретно Боба, а не сайт звонков в качестве получателя медиаданных. Если пользователь дает разрешение, сайт вместо самого медиапотока получает лишь его идентификатор, которым он может пользоваться только для отправки медиаданных Бобу или отображения видео. Если сайт пытается получить доступ к содержанию потока, то API выдает сообщение об ошибке.

Поскольку ненадежный код JavaScript может быть на обеих сторонах WebRTC-соединения, ограничительные механизмы API должны использоваться в обоих браузерах. Откуда Алиса знает, что JavaScript в браузере Боба не записывает звонок, даже если коду в ее браузере это запрещено? В принципе, Алисе нет выгоды от гарантии того, что запись не идет, — Боб является доверенной стороной в рассматриваемой модели угроз, и у него в любом случае есть право записывать звонок. Тем не менее у браузера Боба будет меньше нагрузки по проверке безопасности своего JavaScript, если браузер Алисы сообщит, что определенные медиапотоки следует изолировать. Над стандартом соответствующего сигнала сейчас работают комитеты IETF RTCWEB и TLS.

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

Использование одного и того же ключа для многих сеансов WebRTC упрощает процедуру идентификации — аналогичный метод применяется в протоколе SSH. С другой стороны, открытые ключи могут стать причиной утечки идентификационной информации, если один и тот же ключ используется в разных контекстах. Предположим, что браузер сгенерировал одну пару ключей для сайта вызовов. Если пользователь затем с его помощью сделал звонки на какую-либо конечную точку с применением двух разных идентификаторов от двух разных провайдеров, то вызываемая сторона сможет распознать, что эти два идентификатора принадлежат одному и тому же компьютеру, поскольку оба имеют доступ к одному и тому же закрытому ключу. В сущности, если бы провайдеры идентификации сравнили протоколы, они бы смогли прийти к тому же заключению — как это сегодня иногда происходит с cookie.

Вопросами о том, какой должен быть объем контроля над ключами у вызывающего сайта или провайдера идентификации и как реализовать этот контроль в API, сейчас занимается рабочая группа W3C по WebRTC. Рассматриваются две возможности: разрешить сайту выяснить открытый ключ, который будет использоваться при конкретном соединении, и разрешить запрос нового ключа для соединения. Нельзя, чтобы сайт требовал использования определенной пары ключей, поскольку это нарушает условие контракта с провайдерами идентификации о том, что выдаваемые ими утверждения будут применяться только для WebRTC. Так что основная проблема в том, как выразить две эти возможности.

Применяя ограничительные механизмы API, WebRTC предлагает недоверенному коду JavaScript сбалансированные возможности. С одной стороны, предоставляется достаточно возможностей для создания широкого круга различных приложений и защиты пользователей от слежки, а с другой, можно не допустить, чтобы JavaScript-код получил доступ к пользовательским медиаданным или аутентификационной информации.

Но даже при этих ограничениях остается большой пробел, связанный с воспроизводимыми медиаданными. Предположим, что JavaScript-код, отвечающий за сигнализацию, начинает легитимный аутентифицированный сеанс связи между пользователем и его банком. В нынешней версии WebRTC этот код может проигнорировать защищенные медиаданные и вместо их воспроизведения проиграть мошенническое сообщение из другого источника. Так что, прежде чем отображать какие-либо индикаторы безопасности после аутентификации сеанса связи с банком, браузеру нужно проследить, чтобы они соответствовали воспроизводимым медиаданным. Однако здесь есть тонкости — у приложения WebRTC могут быть легитимные основания использовать медиаданные из иных защищенных источников. К примеру, приложение видео-конференц-связи может воспроизводить входящее аудио и видео из нескольких источников, каждое со своими идентификаторами, возможно, от разных провайдеров. Как браузеру или пользователю отличить такое приложение от мошеннического, получающего медиаданные от двух разных аутентифицированных личностей (банка и мошенника)? Возможные решения этой проблемы сейчас активно обсуждаются рабочей группой по WebRTC.

***

WebRTC предлагает решение проблемы сквозной защиты, которая осталась нерешенной для электронной почты. Надежное обеспечение идентификации по всей системе связи всегда вызывало серьезные сложности. Учитывая, что WebRTC позволяет использовать разные идентификационные системы и то, что для WWW уже создано несколько таких систем, есть надежда, что данную проблему удастся преодолеть. JavaScript-код, предоставляемый сайтами вызовов, создает потенциальную угрозу в браузере, но в API WebRTC есть механизмы, предотвращающие вмешательство такого кода в вызовы. Поддержка этих механизмов уже реализуется в браузерах. Опыт, полученный при организации защиты WebRTC, пригодится в других случаях.

Литература

  1. E. Rescorla. HTTP Over TLS, IETF RFC 2818, May 2000. URL: http://tools.ietf.org/html/rfc2818 (дата обращения: 15.12.2014).
  2. R. Fielding et al. Hypertext Transfer Protocol — HTTP/1.1, IETF RFC 2616, June 1999. URL: http://www.ietf.org/rfc/r fc2616.txt (дата обращения: 15.12.2014).
  3. T. Dierks, E. Rescorla. Transport Layer Security (TLS) Protocol Version 1.2, IETF RFC 5246, Aug. 2008. URL: http://tools.ietf.org/html/rfc5246 (дата обращения: 15.12.2014).

Ричард Барнс (rlb@ipv.sx) — специалист по технологиям безопасности, Мартин Томсон (martin.thomson@gmail.com) — разработчик, компания Mozilla.

Richard Barnes, Martin Thomson, Browser-to-Browser Security Assurances for WebRTC, IEEE Internet Computing, November/December 2014, IEEE Computer Society. All rights reserved. Reprinted with permission.

Поделитесь материалом с коллегами и друзьями

Купить номер с этой статьей в PDF