Canvas-фингерпринтинг рисует скрытую картинку и превращает мельчайшие различия отрисовки в стабильный ID устройства. Как это работает и что реально помогает.
Canvas-фингерпринтинг работает так: браузеру предлагается нарисовать текст и фигуры на невидимом HTML5-холсте (canvas), после чего полученные пиксели считываются обратно и хешируются в короткий стабильный идентификатор. Поскольку каждое устройство отрисовывает одни и те же инструкции немного по-разному — в зависимости от GPU, графического драйвера, операционной системы и шрифтового движка — этот хеш становится тихой подписью, которая следует за вами по сайтам без всяких cookie. Эта статья выходит далеко за рамки основ: как именно расходятся пиксели, сколько уникальности добавляет canvas, как понять, что сайт снимает с вас отпечаток, и почему некоторые популярные средства защиты могут обернуться против вас.
Как на самом деле работает Canvas-фингерпринтинг
Метод опирается на элемент <canvas>, предназначенный для рисования графики с помощью JavaScript. Отслеживающему скрипту никогда не нужно показывать этот холст на экране — он целиком существует в памяти.
Последовательность действий практически одинакова во всех реализациях:
- Создать внеэкранный холст. Небольшой canvas (часто шириной 200–300 px) создаётся, но никогда не добавляется на видимую страницу.
- Нарисовать фиксированную сцену. Скрипт отрисовывает заранее заданную строку текста — нередко с разными шрифтами, цветами, одним-двумя эмодзи и перекрывающимися прямоугольниками. Эмодзи и необычный Unicode популярны, потому что заставляют шрифтовой стек ОС принимать решения об отрисовке.
- Считать пиксели обратно. Скрипт вызывает
toDataURL(), чтобы экспортировать холст как Base64-PNG, либоgetImageData(), чтобы прочитать сырой байтовый массив RGBA напрямую. Это единственные два пути считывания, которые имеют значение для фингерпринтинга — любой скрипт Canvas-фингерпринтинга, независимо от библиотеки, в конечном счёте вызывает один из них. - Хешировать результат. Эти байты пропускаются через хеш-функцию (обычно что-то вроде FNV или MurmurHash), что даёт компактный отпечаток, например
e3b0c44298fc1c14.
Хитрость в том, что инструкции одинаковы для всех, а результат — нет. Два посетителя, запускающие один и тот же скрипт, могут получить разные хеши, а один и тот же посетитель при каждом возвращении получает один и тот же хеш — именно это и нужно трекеру.
Холст никогда не отображается. Вы не увидите ни мерцания, ни рамки, ни какого-либо визуального признака. Именно эта незаметность сделала Canvas-фингерпринтинг таким распространённым для скрытой слежки.
Почему пиксели различаются на разных устройствах
Если рисование слова «Hello» должно быть детерминированным, почему байты вообще меняются? Потому что каждый слой вашей системы вносит в результат свои крошечные, но воспроизводимые отклонения.
GPU и графический драйвер
Сглаживание, субпиксельный рендеринг и способ заливки кривых частично делегируются GPU. Встроенный чип Intel, GPU Apple Silicon и дискретная карта NVIDIA будут по-разному округлять пиксели на краях. Даже две машины с одинаковой моделью GPU могут расходиться, если различаются версии их драйверов.
Растеризация шрифтов
Самый весомый вклад вносит отрисовка текста. Шрифтовой движок ОС — DirectWrite в Windows, Core Text в macOS, FreeType в Linux — решает, как превратить контуры глифов в пиксели. Хинтинг, гамма-коррекция и точный алгоритм сглаживания различаются от платформы к платформе и от версии к версии, поэтому серые пиксели вдоль края буквы «g» несут на удивление много отличительной информации.
Операционная система и установленные шрифты
От того, существует ли запрошенный шрифт, зависит, подставит ли браузер запасной вариант. Эмодзи может отрисоваться плоским контуром на одной системе и полноцветным глифом на другой. Набор цветных эмодзи ОС (Apple, Noto, Segoe) оставляет особенно сильный след.
Браузерный движок и его версия
У Chromium, Firefox и WebKit своя собственная реализация canvas. Управление цветом и способ, которым toDataURL() кодирует PNG-данные, могут меняться от версии к версии браузера — поэтому обновление браузера иногда меняет ваш canvas-хеш.
Сколько уникальности добавляет Canvas?
Canvas ценен для трекеров не потому, что идентифицирует вас в одиночку, а потому что вносит значимую долю энтропии — меры того, насколько сильно один признак сужает круг тех, кем вы можете быть. В исследованиях фингерпринтинга «в дикой природе» canvas неоднократно оказывался среди отдельных сигналов с самой высокой энтропией, которые может прочитать пассивный сайт, наравне с полным списком установленных шрифтов. Самый известный публичный тест этой уникальности — Cover Your Tracks от EFF, хотя его оценку легче истолковать неверно, чем кажется; разбираем это в статье Cover Your Tracks: что не доказывает оценка уникальности.
При этом canvas редко идентифицирует человека сам по себе. Многие используют одинаковые конфигурации — типовой ноутбук на Windows с Chrome и шрифтами по умолчанию совпадёт с миллионами других. Настоящая сила проявляется в сочетании: canvas вместе с WebGL, параметрами экрана, часовым поясом и языком даёт почти уникальный отпечаток. Реальную математику того, «сколько битов нужно набрать, чтобы стать уникальным», и как выглядит итоговое множество анонимности, см. в статье Энтропия отпечатка браузера и множество анонимности.
Почему Canvas-хеш стабилен — пока не перестаёт им быть
У Canvas-отпечатков необычный жизненный цикл, который сбивает с толку многие объяснения: хеш стабилен между сессиями, но не стабилен при смене железа или софта. Важны обе половины, и их смешение — самая распространённая ошибка в описании этой техники.
В пределах одной машины хеш почти не меняется. Один и тот же GPU, одна и та же сборка драйвера, один и тот же растеризатор шрифтов ОС и одна и та же версия браузера каждый раз отрисуют абсолютно одинаковые пиксели — поэтому трекер видит идентичное значение и при вашем первом визите, и при пятисотом, без всякого cookie. Именно эта устойчивость и делает canvas полезным как долгосрочный идентификатор.
Но хеш не вечен. Он сдвигается всякий раз, когда меняется любой слой цепочки рендеринга:
- Обновление драйвера GPU может на несколько субпикселей изменить сглаживание или округление заливки кривых — этого достаточно, чтобы хеш переключился.
- Обновление ОС часто приносит новый растеризатор шрифтов (новую сборку DirectWrite, Core Text или FreeType), незаметно меняя отрисовку каждого глифа.
- Обновление браузера может изменить то, как
toDataURL()кодирует PNG-данные, или то, как сглаживается 2D-контекст canvas, независимо от ОС. - Смена железа (новый ноутбук, другой GPU) даёт совершенно другое значение без какой-либо преемственности со старым.
На практике это значит, что canvas-хеш деградирует как идентификатор за месяцы, а не за дни — он полезен для отслеживания сессии или повторного визита в рамках стабильной конфигурации, но не является постоянным отпечатком в духе серийного номера железа. Трекеры компенсируют это, сочетая canvas с более стабильными сигналами, а не полагаясь на него в одиночку — именно поэтому накопление энтропии (см. ссылку на множество анонимности выше) важнее любого отдельного сигнала.
| Свойство | Canvas-фингерпринтинг |
|---|---|
| Требуется хранилище | Нет (ни cookie, ни localStorage) |
| Переживает очистку кеша/cookie | Да |
| Переживает режим инкогнито/приватный | Обычно да |
| Виден пользователю | Нет |
| Типичный вклад в энтропию | Высокий среди одиночных пассивных сигналов |
| Побеждается очисткой данных | Нет |
| Побеждается сменой IP | Нет |
Как сайты используют Canvas-отпечатки
Canvas-фингерпринтинг — палка о двух концах. Один и тот же механизм работает и на слежку, и на защиту:
- Межсайтовое отслеживание. Рекламные и аналитические сети, встроенные на множество сайтов, читают canvas-хеш, чтобы узнать вернувшегося посетителя даже после очистки cookie, выстраивая поведенческий профиль.
- Защита от мошенничества и безопасность аккаунтов. Банки и платёжные системы помечают входы, где canvas-отпечаток вдруг отличается от известного устройства, помогая выявлять захват аккаунтов.
- Обнаружение ботов и злоупотреблений. Headless-браузеры и фреймворки автоматизации часто выдают canvas-результаты, которые либо слишком однородны, либо отрисовываются характерным образом, поэтому фингерпринтинг помогает отделить реальных пользователей от скриптового трафика — о том, как это работает на практике, см. Методы обнаружения ботов.
- Ограничение частоты запросов и предотвращение злоупотреблений. Сервисы используют отпечаток как стабильный ключ, чтобы ограничивать аккаунты, обходящие лимиты с помощью свежих cookie.
Как определить, снимают ли с вас Canvas-отпечаток
Сам холст вы не увидите, но можете отслеживать поведение, которое его сопровождает.
Следите за вызовами API
При попытке фингерпринтинга JavaScript вызывает getContext('2d'), затем fillText(), затем toDataURL() или getImageData() на холсте, который никогда не добавляется на видимую страницу. Инструменты разработчика браузера и некоторые расширения для приватности могут выявить эти вызовы.
Минимальный перехватчик для обнаружения
Вы можете сами инструментировать canvas API, чтобы логировать подозрительные считывания:
// Обнаружение скриптов, которые читают пиксели холста, ничего не отображая
(function watchCanvasReads() {
const origToDataURL = HTMLCanvasElement.prototype.toDataURL;
const origGetImageData = CanvasRenderingContext2D.prototype.getImageData;
HTMLCanvasElement.prototype.toDataURL = function (...args) {
if (!document.body.contains(this)) {
console.warn('[canvas-fp] toDataURL() on an off-screen canvas', this);
}
return origToDataURL.apply(this, args);
};
CanvasRenderingContext2D.prototype.getImageData = function (...args) {
if (!document.body.contains(this.canvas)) {
console.warn('[canvas-fp] getImageData() on an off-screen canvas', this.canvas);
}
return origGetImageData.apply(this, args);
};
})();
Запускать его нужно раньше собственных скриптов страницы (юзерскриптом на document_start или вставкой в консоль с последующей перезагрузкой), а затем смотреть на предупреждения там, где на странице нет никакой графики. Ложные срабатывания неизбежны: редакторы изображений, библиотеки графиков и инструменты обрезки читают пиксели по делу. Настораживать должно другое — считывание с холста, который вообще не добавлен в документ, на странице без единой графической функции.
Если вы предпочитаете увидеть свой собственный отпечаток, а не читать код, проще всего запустить инструмент проверки отпечатка BrowserInsight. Он вычисляет ваш canvas-хеш в реальном времени, показывает рядом сигналы WebGL и аудио и оценивает, насколько уникален ваш общий отпечаток, — тем же путём считывания, которым пользуется трекер, но целиком в вашем браузере и без отправки данных на сервер.
Способы защиты и их компромиссы
Идеальной защиты не существует, и — что важно — некоторые популярные варианты могут сделать вас более узнаваемым. К тому же никакие два движка не обрабатывают считывание canvas одинаково, а формулировка вроде «браузеры могут добавлять шум» скрадывает как раз те различия, которые и важны при выборе защиты. Вот что каждый производитель на самом деле поставляет сегодня.
Единообразие (resistFingerprinting в Firefox и Tor Browser)
Встроенная настройка Firefox privacy.resistFingerprinting — тот же самый защитный режим, задокументированный Mozilla и включённый по умолчанию в Tor Browser, который построен на Firefox, — использует подход единообразия: считывание холста (toDataURL() или getImageData()) возвращает пустое белое изображение, пока вы явно не разрешите его в запросе доступа, а прочие высокоэнтропийные сигналы — строки производителя и рендерера WebGL, параметры экрана, часовой пояс — сообщаются как фиксированные обобщённые значения, одинаковые для всех защищённых пользователей. Скрипт получает либо бесполезный результат, либо значение, одинаковое для всей защищённой популяции. Слиться с большой однородной толпой — самая надёжная защита, но цена этого — сильно стандартизированный, порой ограничивающий опыт работы в браузере, и именно из-за этого компромисса Mozilla поставляет её как опциональную настройку, а не как поведение Firefox по умолчанию.
Рандомизация (farbling в Brave)
Brave идёт другим путём, который называется farbling: как описывает Brave, он добавляет небольшой детерминированный шум — для каждой сессии и каждого eTLD+1 — в считывание canvas: один и тот же сайт видит устойчивое поддельное значение в рамках сессии, но другое — в следующей сессии или на другом сайте, поэтому межсайтовая связка ломается. Тонкий риск в том, что сам факт рандомизации поддаётся обнаружению — и наивно реализованная рандомизация может парадоксальным образом добавить энтропии, ведь «браузер, у которого canvas зашумлён» — уже отличительная черта. Хорошо спроектированный farbling держит шум малым, детерминированным и правдоподобным, чтобы избежать этой ловушки. Подробнее о том, почему дизайн шума определяет, помогает ли рандомизация или вредит, — в статье Canvas-шум против хеша: почему рандомизация даёт осечку.
Позиция WebKit/Safari в защите от отслеживания
Safari вообще не полагается на шум, специфичный для canvas. Документация WebKit по защите от отслеживания описывает более широкую стратегию, построенную на Intelligent Tracking Prevention: разделение хранилища по сайту верхнего уровня, ограничение доступа скриптов к межсайтовым данным и трактовку устойчивой межсайтовой идентификации в целом как паттерна злоупотребления, который нужно блокировать, а не заклеивать точечно на уровне отдельных API. Считывание canvas в Safari по-прежнему работает — именно на окружающую межсайтовую связку, которая делает отпечаток ценным для трекера, и нацелен ITP.
Chrome и обычный Chromium (защиты нет)
Об этом стоит сказать прямо, потому что это касается большинства читателей: в Chrome нет никакой защиты, специфичной для canvas. toDataURL() и getImageData() отдают ровно те пиксели, которые отрисовали ваш GPU и шрифтовой стек, — и в обычном окне, и в режиме инкогнито. То же верно для Chromium-браузеров, которые не патчат движок сами; Brave выше — заметное исключение. Приватность Google в этой области нацелена на межсайтовую обвязку (политика сторонних cookie, API Privacy Sandbox), а не на то, чтобы сделать сам холст нечитаемым. Если вы пользуетесь Chrome без доработок, считайте свой canvas-хеш полностью открытым.
Блокирующие расширения (CanvasBlocker)
Расширения вроде CanvasBlocker могут блокировать считывание, возвращать поддельное значение или рандомизировать его для каждого домена. Они дают тонкую настройку, но действует та же оговорка: необычная или чрезмерно агрессивная подмена может выделяться, а плохо настроенный блокировщик может оказаться более сильным сигналом, чем тот canvas, который он скрывает.
Отключение JavaScript
Отключение JavaScript (через NoScript или подобное) полностью побеждает Canvas-фингерпринтинг, потому что API просто не может выполниться. Компромисс суров — большинство современных сайтов без него ломаются — поэтому это подходит лишь для самых чувствительных к безопасности сценариев.
| Защита | Как работает | Главный компромисс |
|---|---|---|
| Firefox resistFingerprinting / Tor Browser | Единое значение или заблокированное считывание | Ограниченный, стандартизированный опыт |
| Farbling в Brave | Шум по сессии и по сайту ломает связку | Сама рандомизация может быть заметна |
| Safari (WebKit ITP) | Блокирует межсайтовую связку, а не сам API | Считывание canvas по-прежнему работает; охват уже |
| Chrome / обычный Chromium | Защиты нет — возвращаются настоящие пиксели | Настраивать нечего |
| CanvasBlocker | Блокировка/подмена/рандомизация считывания | Неверная настройка может обернуться против вас |
| Отключение JavaScript | API никогда не запускается | Ломает большинство сайтов |
Часто задаваемые вопросы
Удаляет ли очистка cookie мой canvas-отпечаток?
Нет. Canvas-фингерпринтинг ничего не хранит на вашем устройстве — он выводит идентификатор из того, как ваше железо и софт отрисовывают графику. Очистка cookie, кеша или данных сайта на него никак не влияет.
Останавливает ли приватный режим или инкогнито Canvas-фингерпринтинг?
Обычно нет. Приватные окна изолируют cookie и историю, но ваши GPU, драйверы и шрифты остаются прежними, поэтому canvas-хеш, как правило, такой же, как в обычном окне. Приватный режим помогает против отслеживания на основе хранилища, но не против фингерпринтинга.
Может ли сайт увидеть, что я использую блокировщик canvas?
Иногда да. Если ваш canvas возвращает очевидно поддельное, пустое или зашумлённое значение, изощрённый скрипт может сделать вывод, что активна защита. Именно поэтому единообразие (выглядеть как все) часто надёжнее рандомизации (выглядеть нарочито иначе).
Canvas-фингерпринтинг — это то же самое, что WebGL-фингерпринтинг?
Они связаны, но различны. Canvas читает 2D-отрисовку текста и фигур; WebGL зондирует ваш GPU через 3D-рендеринг и напрямую раскрывает строки производителя и рендерера. В составном отпечатке они дополняют друг друга — наш подробный разбор WebGL-фингерпринтинга детально освещает 3D-сторону.


