Отчёт CreepJS WebRTC: происхождение полей
Свяжите поля отчёта CreepJS WebRTC с API, разбором SDP и частичными результатами, не делая выводов об идентичности.
BotBrowser Team
Нужна структурированная документация по теме Отпечатки?
Эта статья относится к редакционной библиотеке. Для пошаговой настройки, справки и постоянных обновлений переходите сразу в соответствующий раздел docs.
Панель WebRTC в CreepJS представляет составной отчёт, а не захват пакетов или перечень всех возможностей браузера. Сборщик, закреплённый на коммите 10aa6724cd33a1015db1574211890518cd04f0cc, объединяет перечисление типов устройств, шесть запросов декодирования медиа, SDP предложения и выбранные данные событий ICE. BotBrowser документирует настройки кандидатов, прокси и ICE-серверов для разрешённых сценариев; такая настройка не гарантирует достоверность отчёта CreepJS и не устанавливает личность или физический интерфейс.
TL;DR
- Сборщик преобразует строки
enumerateDevices()в типы устройств и сортирует их; этот helper не читает названия устройств. - Он вызывает
decodingInfo()для шести фиксированных аудио- и видеоконфигураций, сохраняет поддерживаемые строки и сводит каждую к признакам плавности и энергоэффективности. - Перед удалением дубликатов и сортировкой у расширений SDP удаляются числовые ID. Отображаемый список не является исходным SDP.
- Первая непустая строка события задаёт
iceCandidateиfoundation; более позднее событие может дополнить результат. - При отсутствии
RTCPeerConnectionсразу возвращаетсяnull. Отдельный трёхсекундный таймер может вернуть частичные поля, поэтомуnull, частичный результат и пропущенное поле не равнозначны.
Содержание
- Границы сборщика и закреплённая версия
- Карта происхождения полей
- Что теряется в полях из SDP
- Поля кандидата и частичные результаты
- Что означает хеш отчёта
- Минимальная запись чтения
- Практический вывод
Границы сборщика и закреплённая версия
Ссылки на код закрепляют конкретную публичную ревизию CreepJS. Утверждения описывают этот исходный код, а не запуск текущего сайта CreepJS, BotBrowser или обычного Chrome. Область уже, чем у руководства по настройке WebRTC: видимые значения сопоставляются с породившими их операциями и ветвями, где реализация отбрасывает, сокращает или ограничивает по времени данные.
Сравнение кодеков WebRTC посвящено API кодеков и совместимости, а пул кандидатов ICE и приватность времени сбора рассматривает предварительный сбор и время событий. Предотвращение утечек WebRTC описывает настройки прокси и ICE. Здесь рассматривается построение отчёта одним сборщиком, а не эксплуатационные настройки.
Карта происхождения полей
| Значение или группа отчёта | Операция в закреплённом источнике | Преобразование или отсутствие | Что это позволяет утверждать |
|---|---|---|---|
mediaDevices | navigator.mediaDevices.enumerateDevices() | Каждая строка преобразуется в kind, затем сортируется; при отсутствии API возвращается null | Типы устройств, полученные helper, но не названия, физические устройства или личность пользователя |
codecsSdp | SDP из createOffer() и ID медиаформатов | Сводит MIME-тип, частоты, каналы, параметры формата и обратную связь | Разобранное представление выбранных возможностей предложения, но не все строки SDP и не успех воспроизведения |
extensions | Строки SDP a=extmap | Удаляет числовой ID, дубликаты и сортирует | Оставшиеся строки расширений, но не исходный порядок или ID |
iceCandidate и foundation | Первое непустое событие icecandidate | Извлекает foundation один раз; ветвь с адресом заменяет известные значения, таймер сохраняет исходное | Первую строку события и значение, зависящее от ветви, а не список интерфейсов |
address | connection.localDescription.sdp | Сначала разбирает строку соединения, затем подстроку вида кандидата; исключает 0.0.0.0 | Адрес, возвращённый парсером, но не доказательство отсутствия других адресов |
foundationProp и stunConnection | Событие, достигшее ветви с допустимым адресом | Возвращаются с адресом; событие может быть позже того, что сохранило iceCandidate | Поля события, завершившего ветвь, а не обязательно события для iceCandidate |
| Отображаемый хеш | codecsSdp, extensions, foundation, foundationProp, address, mediaDevices | Сводит подмножество; iceCandidate и stunConnection в него не входят | Равенство выбранных значений, но не полное совпадение отчётов |
Таблица описывает исходный код, а не измерение. API RTCPeerConnection и спецификация WebRTC W3C задают интерфейс браузера, но приведённые имена и операции относятся к закреплённому сборщику. Даже знакомое название API может быть проекцией с потерей исходных данных.
Что теряется в полях из SDP
Helper расширений извлекает строки extmap, удаляет числовой ID расширения, удаляет дубликаты через Set и сортирует строки лексикографически. Поэтому два предложения SDP с разными ID или исходным порядком могут дать одинаковый список, если оставшиеся строки совпадают. Восстановить исходные строки по нему нельзя.
Список отвечает на вопрос «какие имена расширений сохранились?», но не на вопросы «какой ID был назначен?» и «в каком порядке они шли в предложении?». Эти удалённые значения нельзя выводить из отсортированных строк.
Данные о кодеках также сокращаются. Сборщик читает ID аудио- и видеоформатов из медиасекций, ищет соответствующие строки rtpmap, fmtp и rtcp-fb, затем объединяет записи по MIME-типу. Остаются выбранные поля: частоты, каналы, параметры формата и обратная связь. Это помогает понять, что показывает панель, но не является неизменённой копией SDP и не доказывает, что удалённый участник принял каждый кодек.
Порядок разбора важен. Сначала код находит ID форматов в медиасекциях, затем ищет по всему SDP предложения строки с каждым ID. rtpmap задаёт MIME-тип и частоту; для аудио третий компонент через косую черту используется как число каналов, а если он отсутствует или равен нулю, подставляется один. rtcp-fb добавляется к обратной связи. Другие строки могут дать параметры формата, разделённые точками с запятой. Это поля представления, а не проверка соответствия стандарту.
Повторяющиеся описания кодеков ограничиваются. Записи RTX обрабатываются отдельно; счётчик не позволяет добавить второе описание RTX тем же путём. Записи с одинаковым MIME-типом объединяются: частоты становятся набором уникальных значений, параметры формата и обратная связь также объединяются, если присутствуют. Если медиасекция не содержит ID форматов или подходящих строк, список описаний может быть пустым. Это говорит о том, что нашёл парсер в данном предложении, но не доказывает отсутствие декодера или невозможность воспроизведения.
Это различие полезно, если панель короче исходного SDP. Причиной могут быть группировка, удаление дубликатов, выбранный набор полей или отсутствие совпавшей строки. Это само по себе не означает, что кодек удалён из предложения. Для ответа об оффере отдельно изучите разрешённую и обезличенную копию SDP; не восстанавливайте её по таблице отчёта.
Отдельный helper decodingInfo() создаёт шесть фиксированных конфигураций: четыре аудио и две видео, с фиксированными размерами, битрейтом, частотой кадров, числом каналов и частотой дискретизации. Аудиовходы: Ogg Vorbis, Ogg FLAC, MP4/AAC и MPEG audio; видеовходы: Ogg/Theora и MP4/AVC. Видеопараметры: 1920 на 1080, 120000 бит/с и 60 кадров/с. Параметры аудио: два канала, 300000 бит/с и частота дискретизации 5200. Для аудиозапросов передаётся аудиообъект, для видеозапросов видеообъект.
Сохраняются только ответы с supported: true; метки smooth и efficient добавляются, если соответствующие значения истинны. У поддерживаемой строки может не быть меток, если оба значения ложны. Строка может отсутствовать потому, что редуктор отбросил ответ с supported: false; отклонённый promise записывается в журнал и не создаёт строки для редуктора. Ни одно состояние само по себе не объясняет недоступность формата в другом приложении. Это конкретные запросы, а не все варианты каналов, частоты дискретизации, разрешения, профиля кодека или частоты кадров.
Спецификация Media Capabilities описывает поддержку, плавность и энергоэффективность; закреплённый сборщик выбирает шесть входов и сохраняемые ответы. Справочник decodingInfo() объясняет метод, но не политику отображения. Если приложение использует 30 кадров/с, а отчёт проверяет 60, это разные запросы, и результат одного нельзя переносить на другой. То же относится к частоте дискретизации и числу каналов: запрос с двумя каналами не перечисляет все аудиоконфигурации.
Поля кандидата и частичные результаты
Callback сохраняет первую непустую строку и разбирает её foundation, но продолжает слушать, пока getIPAddress() не найдёт адрес в SDP локального описания. В успешной ветви knownInterface заменяет 842163049 на public interface, а 2268587630 на WireGuard; трёхсекундный таймер возвращает исходное разобранное значение. Поэтому отображаемое значение зависит от ветви завершения и не образует перечень интерфейсов. foundationProp и stunConnection берутся из события, удовлетворившего условию адреса, и могут относиться к более позднему событию, чем iceCandidate.
Есть два разных условия завершения. Если отсутствует window.RTCPeerConnection, сборщик возвращает null до создания соединения. Иначе создаётся соединение с размером пула один и двумя URL Google STUN, канал данных и предложение с параметрами приёма аудио и видео. Код вызывает setLocalDescription(), а затем сразу читает SDP объекта предложения для сводки расширений и кодеков; он не ждёт завершения вызова перед первым разбором.
Затем запускается трёхсекундный таймер, пока обрабатываются события icecandidate. Если таймер срабатывает при наличии SDP предложения, результат может включать поля кодеков, расширений, foundation и кандидата, но не более поздние поля адреса; без SDP возвращается null. Таймер удаляет listener и закрывает соединение. Это окно времени задано кодом, но не доказывает завершение сбора ICE или полноту итогового набора. Универсальной причины для всех этих состояний код не задаёт.
getIPAddress() сначала проверяет строку соединения SDP, затем подстроку, похожую на кандидата. Он исключает 0.0.0.0, но undefined означает только, что код не вернул адрес. Это не доказывает отсутствие интерфейса или кандидата, а также принятие либо отказ удалённого сервиса. Парсер не является сетевым инвентарём: он возвращает одно совпадение по правилу приоритета строки соединения. Руководство о приватности адресов mDNS описывает, что форма адреса может показать и чего не доказывает.
В объекте есть тонкая граница связи полей с событиями. iceCandidate и foundation присваиваются, пока сохранённая строка пуста, то есть удерживают первую непустую строку события. Разбор адреса читает текущий текст connection.localDescription.sdp. Когда событие достигает SDP с разбираемым адресом, callback возвращает foundationProp и stunConnection текущего события. Название «первый кандидат» для всех этих полей смешивает разные правила выбора.
Объект может объединять источники: строку и foundation раннего события, адрес из текущего локального описания и поля события, завершившего ветвь адреса. «Разные источники» описывают ветви кода, а не доказывают гонку, несогласованность или сетевую ошибку. При чтении отчёта сохраняйте это различие, а не утверждайте, что все поля описывают один пакет или интерфейс.
Callback игнорирует события без объекта кандидата и сразу возвращается, если текущий текст локального описания не даёт адреса. Он не завершает сбор после каждого события. Другой путь завершения задаёт таймер; частичный результат содержит меньше свойств, чем ветвь с найденным адресом. Сравнивая два отчёта, сначала проверьте, достигли ли они одной ветви: иначе различие формы объекта может быть связано со временем или доступностью, а не с изменением общего поля.
Что означает хеш отчёта
Код отображения строит вход хеша из codecsSdp, extensions, foundation, foundationProp, address и mediaDevices. Он не включает все возвращаемые значения: iceCandidate и stunConnection отсутствуют во входном объекте. Поэтому изменение строки кандидата может не отразиться в сравнении, если выбранные поля не изменились; наоборот, выбранное поле может изменить сводку, не объясняя причину.
Равенство хеша служит вспомогательным сравнением этой реализации. Оно не доказывает, что браузеры относятся к одному устройству, что совпали полные отчёты или что внешний сайт назначит одинаковый результат. Разные digest говорят только о том, что хотя бы один выбранный вход различается по реализации хеша; сам digest не указывает какой. Совпадение digest не исключает различия пропущенных полей. Сводка помогает определить, что проверить, но не заменяет сами поля.
Производитель отдельно вычисляет mediaDevices. HTML-представление преобразует список в короткие подписи, а хеш включает его вместе с полями SDP. Недоступное или ограниченное разрешениями перечисление устройств может изменить эту часть хеша даже при неизменных полях предложения. И наоборот, изменение предложения может затронуть поле SDP при прежнем списке типов. Хеш объединяет категории из разных API и путей сбора.
Для аккуратного сравнения разделяйте операцию источника, возвращённое значение и отображаемую проекцию. enumerateDevices() возвращает записи устройств; helper оставляет типы; интерфейс сопоставляет им подписи. Исходный список, выход helper и видимая подпись не взаимозаменяемы. Аналогично, decodingInfo() возвращает объект поддержки, редуктор сохраняет подмножество, а панель показывает выбранные поля. Что подтверждает отчёт, определяет путь кода, а не только итоговый текст.
Следующая ревизия CreepJS может изменить фиксированный вход, сохраняемые свойства, таймер или поля объекта хеша. Сравнение только видимой подписи скроет этап изменения. Зафиксируйте ревизию, сравните функции-производители и потребители и обновите соответствующую строку карты происхождения. Описание публичного исходного кода не является заявлением о тестировании браузерной сборки. О границах страницы, сети и продукта см. охват публичных наборов детекторов.
Минимальная запись чтения
Указывайте ревизию и только те различия полей, которые нужны для вопроса. Не храните необезличенные адреса, подписи устройств, полный SDP или строки кандидатов, если достаточно обезличенного состояния. Запись должна указывать, пришло ли значение из API, описания предложения, callback события или интерфейса; отсутствовало ли оно, было ли отфильтровано или вернулось по тайм-ауту.
{
"sourceCommit": "10aa6724cd33a1015db1574211890518cd04f0cc",
"field": "extensions",
"sourceOperation": "getExtensions(sdp)",
"steps": ["remove numeric extmap id", "deduplicate", "sort"],
"state": "parsed",
"interpretationLimit": "not original SDP order or extension IDs"
}
Пример записывает путь кода, а не наблюдение браузера. Если отдельное расследование требует данных выполнения, собирайте их по разрешённому плану и обезличивайте перед передачей; опубликованный исходный код не содержит записи о таком запуске. Не храните полный SDP или открытый адрес только для доказательства того, что парсер вернул поле. Состояние вроде addressPresent, имя ветви и ревизия могут ответить на вопрос с меньшим объёмом данных. Запись нельзя представлять как свидетельство личности или удалённого решения.
FAQ
Хеш WebRTC CreepJS идентифицирует браузер?
Нет. Код хеширует выбранные поля. Он не включает все возвращаемые значения и не доказывает конкретное устройство, человека или решение внешнего сервиса.
Отсутствующий адрес доказывает, что WebRTC выключен?
Нет. Парсер может не вернуть адрес, хотя другие данные есть, а таймер может вернуть частичный результат. При отсутствии RTCPeerConnection используется отдельная немедленная ветвь null.
Список расширений является исходным SDP?
Нет. Числовые ID удаляются, дубликаты убираются, значения сортируются. Исходный порядок и ID восстановить нельзя.
decodingInfo() показывает все поддерживаемые форматы?
Нет. Сборщик проверяет шесть фиксированных конфигураций и сохраняет выбранные свойства поддерживаемых ответов. Иная конфигурация, версия браузера или контекст устройства могут дать другой результат.
Источники
- Закреплённый сборщик WebRTC CreepJS
- WebRTC W3C
- RFC 8866: SDP
- Media Capabilities W3C
- MDN: RTCPeerConnection
- MDN: MediaCapabilities.decodingInfo()
- Предотвращение утечек WebRTC в BotBrowser
Практический вывод
Читайте панель WebRTC CreepJS как набор полей с разными источниками и обработкой. Сохраняйте ревизию кода, отличайте отсутствующий API от тайм-аута и отфильтрованного результата и не превращайте частичный отчёт или хеш выбранных полей в утверждение об устройстве, личности либо вердикте.
Эта статья входит в руководство: Что такое утечка IP через WebRTC? Защита и конфиденциальность
Похожие статьи
Сигналы Math в CreepJS: источники полей
ОтпечаткиАудиоотчёт CreepJS: рендеринг и пропуски
ОтпечаткиОтчёт BrowserLeaks WebGL: сбор и отсутствующие данные
ОтпечаткиОтчёт CreepJS WebGL: контексты и сигналы
ОтпечаткиFingerprinting кодеков WebRTC: утечка медиавозможностей
ОтпечаткиОтчёт Intl CreepJS: поля и отсутствующие значения
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.