NimbusX
00
› страница получена
← блог
отпечаток08.08.20269 мин

Как детекторы связывают профили

Антифрод сравнивает не cookie. Он складывает измерения браузера в один слепок и ищет совпадения между аккаунтами. Разбираем, из чего слепок собран, что в нем весит больше всего и почему подмены одного canvas недостаточно.

01Слепок вместо cookie

Сайт видит не «браузер», а сумму измерений. Каждое по отдельности слабое, вместе они дают отпечаток, который переживает чистку cookie и смену IP. Порядок примерно такой:

КаналЧто измеряетсяНасколько различает
Список шрифтовкакие шрифты установлены в системенаибольшая энтропия: 9,45 бита, 35% машин уникальны
WebGLстрока видеокарты, параметры отрисовкивысокая, привязана к железу
Canvasхэш отрисованной картинкивысокая
Аудиохэш сигнала через Web Audioвысокая на разных машинах
Экран и DPRразрешение и плотность пикселейсредняя
Часовой пояс, языкнастройки системынизкая по отдельности, важна согласованность

Шрифты стоят первыми не случайно: это поверхность с наибольшей энтропией. 35% машин по одному только списку шрифтов уникальны в потоке.

02Что мы замерили на старте

Первый замер проекта дал неприятный результат. Два профиля на одной машине без набора устройств совпадали по метрикам шрифтов, параметрам WebGL, clientRects и аудио при любой конфигурации. Сайт связывал такие аккаунты независимо от cookie и IP. Этот замер определил всю архитектуру продукта.

Ответ оказался не в том, чтобы «зашумить все», а в том, чтобы дать каждому профилю согласованный набор с настоящего компьютера. После подключения набора устройств те же поверхности стали различаться. Проверено на живых браузерах:

ПоверхностьРазличается у двух профилей
WebGL вендор и рендерерда
Параметры WebGLда
Геометрия экрана и DPRда
Число ядер и памятьда
Список шрифтовда
Голоса синтеза речида
Таблица констант Web Audioда
Canvasда, шум от сида профиля

03Почему подмены одного canvas мало

Подмененный canvas при настоящем списке шрифтов ничего не решает: связка происходит по нетронутым каналам. Хуже того, часть каналов трогать нельзя.

Метрики текста общих шрифтов движок намеренно не искажает. У детекторов есть проверка measuretext-grid, которая ловит именно искажение; подделка сделала бы браузер обнаружимым. То же с clientRects (проверка bcr-vs-range). Эти поверхности и не различают: на двух настоящих машинах с одинаковой ОС и DPR ширина Arial совпадет, потому что ее задает файл шрифта и система, а не человек.

Ошибка, которая едва не увела в неверную сторону. Первая версия нашей проверки мерила ширины восемнадцати общих шрифтов и показывала совпадение всегда. Напрашивался вывод «набор устройств не работает». На деле машины различает список установленных шрифтов, а не метрики общих. После замены методики картина стала обратной: профиль B видит три своих эксклюзивных шрифта, профиль A не видит ни одного чужого.

04Как это проверить самому

Не на слово. Создайте два профиля на бесплатном тарифе, откройте в каждом страницу проверки и сравните сырые значения:

$ python -m app.cli profile create --name link-a $ python -m app.cli profile create --name link-b # запустите оба профиля и откройте nimbusx.app/check

Canvas и WebGL различаются, наборы согласованы. Это видно в сырых значениях, а не в нашем описании. Или откройте тест отпечатка: он снимет ваш браузер и поставит рядом набор профиля.

05Честный остаток

Один канал пока связывает профили на одной машине. Хэш отрисованного аудио: шум движка привязан к домену, а не к профилю. На двух реальных компьютерах хэши разные, у наших профилей на одной машине они одинаковые. Мы показываем это в панели, в ячейке АУД у каждого профиля, а не в сноске. Практическое правило до собственной сборки движка: профили одной площадки держать на разных машинах.

06Читать дальше

Аудио-отпечаток: честный остаток · Согласованность важнее количества

Скачать NimbusXВопрос по разбору: @Get_NimbusX_Bot