Фингерпринтинг WebRTC читает список кодеков и SDP-предложение, а не ваш IP. Как это работает, чем отличается от утечки WebRTC и как это снизить.
Фингерпринтинг WebRTC опознаёт ваш браузер по списку поддерживаемых аудио/видео кодеков и по точной структуре SDP (Session Description Protocol) — текста, который браузер генерирует для согласования звонка, — вообще не затрагивая ваш IP-адрес. Скрипту достаточно вызвать один статический метод, чтобы получить структурированный список кодеков и заголовочных расширений, и использовать форму этого списка, чтобы отличать браузеры, движки и платформы друг от друга. Это совершенно иной механизм, чем хорошо известная утечка IP через WebRTC, и путаница между ними создаёт ложное чувство безопасности: устранение одной проблемы никак не влияет на другую.
Ключевые выводы
- Фингерпринтинг WebRTC читает поддержку кодеков и структуру SDP — он никогда не затрагивает ваш публичный или локальный IP-адрес, поэтому не имеет отношения к классической утечке WebRTC.
- Основной сигнал даёт
RTCRtpSender.getCapabilities()— статический метод, который возвращает список поддерживаемых кодеков без единого запроса разрешения и без сетевого трафика. - SDP-текст, который генерирует
createOffer(), добавляет второй слой: нумерацию типов полезной нагрузки, порядок кодеков и параметры для каждого кодека вродеprofile-level-idилиpacketization-mode. - Сам по себе этот сигнал довольно грубый — он в основном различает движок браузера, версию и платформу, а не однозначно опознаёт конкретного человека, — но он добавляет ещё один слой поверх canvas, WebGL и аудиоотпечатков.
- Полное отключение WebRTC убирает эту поверхность целиком; со временем значение меняют в основном обновления браузера и поддержка аппаратных кодеков на уровне ОС.
Что такое фингерпринтинг WebRTC?
Каждый браузер, реализующий WebRTC, несёт в себе определённый набор аудио- и видеокодеков в определённом порядке и с определёнными параметрами. Браузеры на основе Chromium, Firefox и Safari построены на разных базовых медиастеках, поэтому точный список кодеков — и то, какие кодеки получают аппаратное ускорение на конкретной ОС — различается между ними. Скрипт может прочитать этот список напрямую либо заставить браузер сформировать SDP-предложение и использовать любой из этих вариантов как сигнал устройства/браузера.
Важно понимать, что это не тот же класс риска, что утечка IP через WebRTC, где процесс ICE/STUN может раскрыть ваш реальный публичный IP даже за VPN. Фингерпринтинг по кодекам и SDP раскрывает чем является ваш браузер, а не где вы находитесь. У вас может быть нулевая утечка WebRTC (полностью проксированный, грамотно настроенный VPN) и при этом совершенно обычный отпечаток по кодекам — и наоборот.
Чтение возможностей кодеков без установления соединения
Самая простая и незаметная техника вообще не требует создания peer connection. RTCRtpSender.getCapabilities(kind) — статический метод: он немедленно возвращает поддерживаемые браузером кодеки и заголовочные расширения без запроса разрешения, без сигнализации и без какой-либо сетевой активности:
function getWebRTCCodecFingerprint() {
if (!window.RTCRtpSender || !RTCRtpSender.getCapabilities) {
return { supported: false };
}
const audio = RTCRtpSender.getCapabilities('audio');
const video = RTCRtpSender.getCapabilities('video');
return {
supported: true,
audioCodecs: audio.codecs.map((c) => c.mimeType),
videoCodecs: video.codecs.map(
(c) => `${c.mimeType}${c.sdpFmtpLine ? ' ' + c.sdpFmtpLine : ''}`
),
headerExtensions: video.headerExtensions.map((h) => h.uri),
};
}
Возвращаемый массив codecs включает MIME-тип, тактовую частоту, число каналов каждого кодека и опциональную sdpFmtpLine, несущую параметры, специфичные для кодека. Массив headerExtensions перечисляет поддерживаемые RTP-заголовочные расширения (используемые, например, для уровня громкости и управления перегрузкой на уровне транспорта), и их наличие и порядок тоже варьируются в зависимости от движка и версии.
Что попадает в SDP-предложение
Если скрипт идёт на шаг дальше и действительно вызывает createOffer(), итоговый SDP-текст раскрывает ту же информацию в более детализированном виде: номера типов полезной нагрузки, порядок кодеков и построчные атрибуты для каждого кодека. Урезанный, иллюстративный видеораздел выглядит так:
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 102 127
a=rtpmap:96 VP8/90000
a=rtpmap:98 VP9/90000
a=rtpmap:102 H264/90000
a=fmtp:102 profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1
a=rtpmap:127 AV1/90000
Сам формат SDP — это стандартизированный текстовый протокол IETF — интересен для фингерпринтинга не синтаксис сам по себе, а конкретная комбинация номеров типов полезной нагрузки, порядка кодеков и параметров fmtp, которую выбирает именно ваш браузер/ОС/версия. Два браузера на разных платформах редко воспроизводят в точности одну и ту же комбинацию.
Чем это отличается от утечки IP через WebRTC
Стоит явно обозначить границу, потому что обе техники используют одну кодовую базу (WebRTC), но не имеют между собой больше ничего общего:
| Утечка IP через WebRTC | Фингерпринтинг по кодекам/SDP WebRTC | |
|---|---|---|
| Что раскрывает | Ваш реальный публичный/локальный IP-адрес | Движок вашего браузера, версию и платформу |
| Механизм | Сбор ICE-кандидатов через STUN/TURN | getCapabilities() и/или содержимое SDP-предложения |
| Нужен ли сетевой обмен? | Да — требуется обращение к STUN-серверу | Нет — getCapabilities() полностью локальна |
| Обходит ли VPN? | Может, если маршрутизация утекает за пределы туннеля | Неприменимо — данные о местоположении не задействованы |
| Как исправить | Ограничить/отключить WebRTC или использовать VPN без утечек | Отключить WebRTC или сократить поверхность кодеков |
Если вы уже закрыли утечки WebRTC, это защищает ваше местоположение — но никак не влияет на сигнал кодеков/SDP, поскольку getCapabilities() вообще не запрашивает сетевой доступ.
Насколько отличителен этот сигнал?
Фингерпринтинг по кодекам и SDP — сравнительно грубый сигнал. Поскольку Chrome, Edge, Opera и Brave построены на одном и том же фундаменте Chromium/libwebrtc, они склонны сообщать очень похожие списки кодеков — этот сигнал в основном разделяет семейства движков (Chromium vs. Gecko vs. WebKit) и платформы (какие аппаратные декодеры ОС предоставляет браузеру), а не вычленяет конкретного человека.
| Фактор | Что раскрывает |
|---|---|
| Список и порядок кодеков | Семейство и версию движка рендеринга |
Параметры sdpFmtpLine (например, profile-level-id для H.264) | Медиастек платформы и поддержку аппаратных декодеров |
| Список заголовочных расширений | Версию движка, иногда включённые экспериментальные функции |
| Наличие AV1/HEVC | Возможности ОС и аппаратного ускорения |
Это делает его довольно скромным вкладчиком сам по себе — в духе аудио-фингерпринтинга: недостаточно, чтобы опознать вас в одиночку, но ещё один независимый источник битов, который складывается с сигналами canvas и WebGL, ещё сильнее сужая круг.
Медиавозможности за пределами кодеков
Стоит знать о смежном, но отдельном API — Media Capabilities API, а именно о navigator.mediaCapabilities.decodingInfo(). Он не входит в состав WebRTC, но его часто проверяют вместе с ним, потому что он отвечает на похожий вопрос — что на самом деле умеет медиаконвейер устройства, — сообщая, будет ли декодирование заданной комбинации кодек/разрешение/частота кадров smooth (плавным) и powerEfficient (энергоэффективным, то есть аппаратно ускоренным). Поскольку поддержка аппаратного ускорения привязана к конкретному GPU и медиафреймворку ОС, это добавляет ещё один, «аппаратный» по духу сигнал поверх программного списка кодеков, который раскрывает WebRTC.
Способы защиты и их компромиссы
| Подход | Эффект | Компромисс |
|---|---|---|
Отключить WebRTC (media.peerconnection.enabled в Firefox) | Убирает и сигнал кодеков/SDP, и поверхность утечки IP | Полностью ломает звонки и видеосвязь в браузере |
| Tor Browser | WebRTC отключён по умолчанию | Та же потеря функциональности, но одинаковая для всех пользователей Tor |
| Ограничить набор кодеков через расширение | Может сократить сообщаемые кодеки | Мало массовых расширений нацелены именно на этот сигнал — большинство фокусируется на утечке IP |
| Принять сигнал как есть, сосредоточиться на другом | Функциональность не теряется | Для большинства моделей угроз фингерпринтинг по кодекам — низкоценная цель по сравнению с canvas/WebGL |
Выделенного массового переключателя «рандомизировать мой список кодеков», как для canvas или аудио-farbling, попросту не существует — в основном потому, что сигнал грубее и менее ценен, чем те. Для большинства людей практичный вывод — воспринимать его как ещё один вклад поверх более высокоэнтропийных сигналов, а не как отдельную битву, за которую стоит сражаться.
Как проверить собственный сигнал
Вы можете увидеть, что раскрывает ваш браузер, без единой строчки кода:
- Запустите проверку отпечатка от BrowserInsight, чтобы увидеть свой общий профиль отпечатка, включая то, какую долю вашей общей уникальности вносят такие низкоэнтропийные сигналы.
- Откройте консоль разработчика в браузере и выполните приведённый выше фрагмент
getWebRTCCodecFingerprint(), чтобы увидеть свой необработанный список кодеков. - Сравните один и тот же тест в Chrome, Firefox и Safari на одной машине — порядок кодеков и параметры
fmtpобычно различаются между движками даже на идентичном железе. Проект EFF Cover Your Tracks — хорошая дополнительная проверка того, как ваша общая конфигурация выглядит на фоне других.
Часто задаваемые вопросы
Раскрывает ли фингерпринтинг WebRTC мой IP-адрес?
Нет. Фингерпринтинг по кодекам и SDP читает то, что поддерживает ваш браузер, используя RTCRtpSender.getCapabilities() или содержимое SDP-предложения — ни то, ни другое не затрагивает ваш сетевой адрес. Раскрытие IP — отдельный механизм (утечка WebRTC), описанный в нашем руководстве Защита от утечек WebRTC.
Устраняет ли отключение WebRTC и утечку, и отпечаток одновременно?
Да — полное отключение WebRTC (или использование браузера вроде Tor, который отключает его по умолчанию) убирает обе поверхности сразу, поскольку ни getCapabilities(), ни согласование SDP не могут работать без включённого WebRTC. Компромисс в том, что видеозвонки и голосовая связь в браузере перестают работать.
Настолько же ли отпечаток по кодекам идентифицирует, как canvas- или WebGL-отпечаток?
Нет, обычно он слабее. Поскольку основные браузеры на базе Chromium используют один и тот же нижележащий стек libwebrtc, их списки кодеков выглядят похоже, поэтому сигнал в основном раскрывает семейство движка и платформу, а не точно указывает на конкретного человека. Он всё же добавляет вклад в общую сумму энтропии, просто меньший, чем сигналы рендеринга.
Может ли сайт прочитать список моих кодеков без запроса разрешения?
Да. RTCRtpSender.getCapabilities() — статический метод, который выполняется без запроса разрешения на камеру/микрофон и без сетевого запроса — он просто сообщает, что поддерживает реализация WebRTC в браузере.
Заключение
Фингерпринтинг WebRTC и утечка IP через WebRTC живут в рамках одного и того же API, но раскрывают совершенно разные вещи: один — ваш реальный сетевой адрес, другой — движок вашего браузера, версию и платформу через поддержку кодеков и структуру SDP. Одно не заменяет другое. Сам по себе фингерпринтинг по кодекам/SDP — скромный, грубый сигнал, но понимание этого убережёт вас от ошибки — принять настройку VPN без утечек за настройку, защищённую и от фингерпринтинга.
Рекомендуем прочитать:


