FingerprintJS — открытая библиотека, отдельная от платного продукта Fingerprint. Что она собирает, насколько точна и чем отличается от CreepJS.
Если поискать «fingerprintjs», в выдаче смешаются две разные вещи. Первая — открытая JavaScript-библиотека, которую можно бесплатно подключить к любой странице: она работает целиком в браузере посетителя и возвращает строку visitorId. Вторая — Fingerprint, платный коммерческий сервис идентификации от той же компании: он добавляет серверную обработку и заявляет гораздо более высокую точность. У них общее название, общая организация на GitHub и общий подход — свести множество браузерных сигналов в один идентификатор, — но на этом сходство почти заканчивается. Эта статья о первой: какие сигналы открытая библиотека реально считывает, как превращает их в visitorId, насколько она точна на самом деле и чем отличается от других тестов отпечатка, которые мы уже разбирали.
Ключевые выводы
- Бесплатная библиотека FingerprintJS под лицензией MIT и платный продукт Fingerprint сделаны одной компанией, но это не одно и то же. Библиотека работает полностью на стороне клиента, и её собственный README признаёт, что её точность «значительно ниже», чем у коммерческой версии.
- Библиотека считывает около 40 браузерных сигналов — отрисовку canvas, установленные шрифты, обработку аудио, сведения о рендерере WebGL, параметры экрана и оборудования, часовой пояс и язык, настройки отображения и другое — и хеширует их в единый
visitorId. visitorIdотвечает на вопрос «тот же ли это браузер, что и в прошлый раз?». Это вопрос стабильности, и он отличается от вопроса CreepJS «не лжёт ли браузер о себе?» и вопроса Cover Your Tracks «насколько редка эта комбинация?».- Поскольку отпечаток не зависит от cookie и хранилища, он переживает режим инкогнито и очистку данных браузера. Но он меняется, когда меняются сами сигналы, — например, после обновления браузера или графического драйвера, а также в браузерах, которые намеренно рандомизируют поверхности фингерпринтинга.
- README не приводит процент точности для открытой библиотеки, поэтому не приводим его и мы. К любым конкретным цифрам, которые ей приписывают, стоит относиться осторожно.
Два разных «FingerprintJS»
Путаница заложена в самой истории проекта. Компания FingerprintJS Inc. начинала с открытой библиотеки, затем построила на той же идее коммерческий продукт, а сейчас работает под названием Fingerprint. Библиотека по-прежнему поддерживается, и именно её вы получаете командой npm install @fingerprintjs/fingerprintjs, — но большая часть маркетинга компании и многие сторонние тексты о «FingerprintJS» описывают возможности платного продукта, которых у бесплатной библиотеки нет.
Различия, которые важны при выборе:
- Где выполняется. Открытая библиотека всё вычисляет в браузере посетителя и отдаёт странице
visitorId. Коммерческий продукт дополнительно обрабатывает каждый запрос на серверах вендора, где может использовать сигналы, недоступные скрипту на странице (например, IP-адрес подключения), и сопоставлять визит с предыдущими. - Стоимость. Библиотека бесплатна и распространяется по лицензии MIT. Коммерческий продукт — платный API с оплатой по объёму использования.
- Что заявляется. README прямо говорит: поскольку библиотека генерирует отпечатки в браузере, её точность значительно ниже, чем у коммерческой версии. Вендор рекламирует куда более высокую точность платного продукта именно благодаря этому серверному слою.
Если вы искали «fingerprintjs», рассчитывая найти бесплатную библиотеку, которую можно развернуть у себя, — это открытый проект. Если же вы подбираете решение против мошенничества или ботов для бизнеса, речь на самом деле о коммерческом продукте, и сравнивать их как один инструмент под разными вывесками не стоит.
Что реально считывает открытая библиотека
Если отбросить брендинг, библиотека использует те же техники, что разобраны в других статьях на сайте: фиксированный набор клиентских сигналов, которые собираются и хешируются в одно значение. В исходном коде каждый сигнал оформлен как «источник энтропии» (entropy source) — в текущей версии их около 40. По группам:
- Отрисовка canvas. Техника скрытой отрисовки из статьи «Canvas-фингерпринтинг: как сайты узнают ваше устройство»: один и тот же текст и фигуры отрисовываются с мельчайшими пиксельными различиями в зависимости от GPU, драйвера и рендеринга шрифтов, что даёт стабильный хеш без всяких cookie.
- WebGL. Базовые параметры WebGL — например, строки производителя (vendor) и рендерера (renderer), — а также список поддерживаемых расширений WebGL.
- Аудио. Короткий сигнал, обработанный через Web Audio API (механизм описан в статье «Аудио-фингерпринтинг: как AudioContext опознаёт устройство»), плюс базовая задержка, которую сообщает аудиостек. Различия возникают из-за реализации аудио и оборудования, а не из-за каких-либо настроек пользователя.
- Шрифты. Какие шрифты установлены и как отрисовываются семейства шрифтов по умолчанию. И то и другое зависит от ОС, языковых пакетов и установленных программ.
- Экран и оборудование. Разрешение экрана и глубина цвета, место, которое ОС резервирует вокруг рабочей области экрана (например, под панель задач или Dock), число ядер процессора (
hardwareConcurrency), приблизительный объём памяти устройства и поддержка сенсорного ввода. - Региональные настройки. Часовой пояс, предпочитаемые языки и локаль, используемая для форматирования даты и времени.
- Платформа и браузер. Заявленная платформа и архитектура процессора, производитель браузера, установленные плагины, включён ли встроенный просмотрщик PDF, а также несколько проверок, специфичных для движков, например доступность Apple Pay.
- Предпочтения и окружение. CSS-медиафункции: цветовой охват, принудительные или инвертированные цвета, предпочтения по контрасту и уменьшению анимации, поддержка HDR; доступность cookie и API хранилищ; какие блокировщики контента, судя по всему, активны; мелкие различия в вычислениях с плавающей точкой у функций
Math.
Ни один из этих сигналов не уникален для FingerprintJS — статья «Цифровой отпечаток браузера: как защитить приватность» описывает те же базовые техники в общем виде. Вклад библиотеки — в упаковке: поддерживаемый скрипт собирает весь набор и превращает его в одну строку, так что сайту не нужно писать логику сбора самому.
От сигналов к visitorId
Метод get() возвращает четыре поля: visitorId; оценку confidence, показывающую, насколько библиотека уверена в этом идентификаторе; собранные «сырые» components; и version — версию алгоритма фингерпринтинга. Сам visitorId — это 128-битный хеш (функция библиотеки x64hash128, вариант MurmurHash3) от всех компонентов, сериализованных в одну строку. Стоит измениться любому компоненту — и хеш получится совершенно другим: «почти такого же» visitorId не бывает.
Насколько она точна на самом деле
В README есть два утверждения, которые стоит разделять. Первое: отпечаток не зависит от cookie и локального хранилища, поэтому он «остаётся прежним в режиме инкогнито/приватном режиме и даже после очистки данных браузера». Именно ради этого сайты и используют фингерпринтинг: удаление cookie его не сбрасывает.
Второе: по словам README, поскольку FingerprintJS генерирует отпечатки внутри браузера, её точность значительно ниже, чем у коммерческой версии. Процента README не называет — не будем называть и мы.
Почему ниже? Из того, как устроен visitorId, напрямую следуют две структурные причины. Это наш анализ, а не утверждение проекта:
- Дрейф. Хеш охватывает все компоненты, поэтому изменение любого сигнала даёт новый
visitorId. Обновление браузера может изменить отрисовку текста на canvas; обновление графического драйвера — вывод canvas или строку рендерера WebGL; установка шрифта меняет список шрифтов. Браузеры с защитой от фингерпринтинга, которые намеренно добавляют шум в вывод canvas или аудио, могут возвращать разные значения от сессии к сессии или от сайта к сайту. Вернувшийся посетитель, у которого сигналы сдвинулись, выглядит как совершенно новый. - Коллизии. Обратная проблема: устройства одной модели с одинаковой версией ОС и сборкой браузера — скажем, парк одинаково настроенных офисных ноутбуков или два iPhone одной модели на одной версии iOS — могут отдавать почти идентичные сигналы и получать один и тот же
visitorId, так что разные люди выглядят как один посетитель.
Скрипт, работающий только в браузере, не может исправить ни одну из этих ошибок сам. Серверная система способна учитывать дополнительные данные — например, из какой сети пришёл визит и какова история прошлых посещений, — и именно этот пробел призван закрыть коммерческий продукт.
Место FingerprintJS среди других тестов
visitorId от FingerprintJS отвечает на один конкретный вопрос: тот же ли это браузер, что и раньше? Это вопрос стабильности, и важно чётко понимать, чем он отличается от других инструментов, разобранных на сайте, — ведь один и тот же браузер может получить три совершенно разных на слух вердикта в зависимости от того, какой вопрос задан:
- CreepJS спрашивает говорит ли браузер правду о себе? — это проверка согласованности, которая сверяет доверенные и недоверенные источники сигналов в поисках внутренних противоречий. Браузер может выглядеть безупречно согласованным по меркам CreepJS и при этом выдавать очень стабильный и легко отслеживаемый
visitorId. - Cover Your Tracks спрашивает насколько редка эта комбинация сигналов? — вопрос уникальности, на который отвечают средствами теории информации; он не связан ни с согласованностью сигналов, ни с их стабильностью от сессии к сессии.
- FingerprintJS не задаёт ни одного из этих вопросов. Её интересует, даст ли тот же набор сигналов, захешированный тем же способом, тот же идентификатор ещё раз, — вопрос воспроизводимости, который ничего не говорит ни о том, насколько распространена комбинация, ни о том, не подделан ли какой-то отдельный сигнал.
Статья «Почему тесты отпечатка браузера расходятся в оценках» разбирает эту закономерность в целом: уникальность, согласованность и стабильность идентичности — три разных измерения, которые часто подаются под одними и теми же расплывчатыми словами «оценка» или «ID», а инструмент, созданный для одного из них, и не пытался отвечать на два других. Если вы сравнивали результат вроде visitorId с оценкой доверия CreepJS или показателем анонимности Cover Your Tracks и не могли свести их воедино — это нормально: они отвечают на разные вопросы. Статья «BrowserLeaks: что именно проверяет каждый тест» дополняет картину четвёртым типом таких инструментов — набором тестов, который сообщает результат по каждой поверхности отдельно и ничего не сводит в единую цифру.
Проверьте собственные сигналы
Проверка отпечатка BrowserInsight показывает многие из тех же категорий сигналов, что считывает эта библиотека, — canvas, WebGL, аудио, шрифты, экран и свойства navigator — по отдельности, вместе с проверками согласованности, которые отмечают, когда сигналы противоречат друг другу. Собственный visitorId она не вычисляет. Вместо этого она показывает «сырые» поверхности, которые захешировала бы библиотека фингерпринтинга, чтобы вы видели, какие из них выделяют ваш браузер. Чтобы увидеть дрейф своими глазами, запустите проверку, затем обновите браузер или включите в нём защиту от фингерпринтинга (если она есть) и запустите снова: изменившееся значение canvas, WebGL или шрифтов — ровно тот сдвиг, который дал бы и новый visitorId.
Часто задаваемые вопросы
Открытая библиотека FingerprintJS — это то же самое, что продукт Fingerprint?
Нет. Их делает одна компания, и подход у них общий — на основе хеширования, но открытая библиотека работает целиком на стороне клиента и, по её собственному README, значительно менее точна, а платный продукт Fingerprint добавляет серверную обработку, которой у бесплатной библиотеки нет.
Можно ли использовать открытую библиотеку на коммерческом сайте?
Библиотека опубликована под лицензией MIT, которая разрешает коммерческое использование. Точные условия смотрите в файле лицензии в репозитории.
Собирает ли FingerprintJS данные обо мне и хранит ли их?
Сама открытая библиотека — это скрипт, который выполняется в вашем браузере и возвращает visitorId. Что происходит с идентификатором дальше — сохраняется ли он и где, — полностью зависит от сайта, который её использует, а не от библиотеки. Смотрите политику конфиденциальности конкретного сайта, а не стройте предположения о том, как обрабатывается результат скрипта фингерпринтинга.
Почему мой visitorId меняется между визитами?
Потому что это хеш от всех сигналов, которые считывает библиотека, и изменение любого из них даёт другой ID. Частые причины — обновления браузера и графического драйвера, новые установленные шрифты, а также функции защиты от фингерпринтинга, рандомизирующие вывод canvas или аудио. А вот открытие окна инкогнито или очистка cookie менять его не должны — по словам README, в обоих случаях отпечаток остаётся прежним.
FingerprintJS точнее, чем CreepJS или Cover Your Tracks?
Такое сравнение не вполне осмысленно, потому что эти три инструмента измеряют разное. FingerprintJS проверяет, получает ли один и тот же посетитель один и тот же идентификатор дважды; CreepJS — согласованы ли сигналы браузера между собой; Cover Your Tracks — насколько редка комбинация. «Точнее» имеет смысл, только когда два инструмента отвечают на один и тот же вопрос.
Рекомендуем прочитать
- Почему тесты отпечатка браузера расходятся в оценках
- CreepJS: как детектор лжи ловит подмену отпечатка
- BrowserLeaks: что именно проверяет каждый тест
- Canvas-фингерпринтинг: как сайты узнают ваше устройство
- Аудио-фингерпринтинг: как AudioContext опознаёт устройство
- Цифровой отпечаток браузера: как защитить приватность


