Отпечаток Canvas: как он работает и что помогает
Как различия в отрисовке Canvas превращаются в стабильный идентификатор, почему VPN и приватный режим его не меняют и как работает детерминированный вывод по профилю.
BotBrowser Team
Нужна поддерживаемая продуктовая документация?
У этой статьи есть соответствующая страница в центре документации. Используйте docs для каноничного сценария настройки, актуальных флагов и долгосрочной справки.
BotBrowser может обеспечить воспроизводимое чтение Canvas в авторизованном тесте с явно указанными профилем и seed. Он не гарантирует анонимность, принятие сайтами или одинаковую отрисовку на разных компьютерах и графических стеках.
Кратко
Отпечаток Canvas создают отрисованные пиксели, поэтому очистка хранилища или смена IP его не меняет. Сравнивайте объявленные профиль, --bot-noise-seed, дисплей, шрифты и графический backend; совпадение вывода является ограниченным результатом Canvas, а не доказательством личности или принятия сайтом.
Содержание
- Что измеряет отпечаток Canvas
- Почему один и тот же рисунок различается на разных устройствах
- Почему VPN, приватный режим и расширения не решают задачу
- Четыре способа обращения с выводом Canvas
- Как BotBrowser обращается с Canvas
- Проверка стабильности и разбор расхождений
Посмотреть контролируемую демонстрацию Canvas
В этом видео на английском языке сравнивается синтетический canvas до и после намеренного изменения одного байта. Оно показывает сравнение байтов пикселей в контролируемой локальной среде, но не доказывает идентичность устройства или естественные различия между устройствами.
Элемент Canvas в HTML5 создан для рисования. Диаграммы, карты, графические редакторы, поля для подписи, игры и панели мониторинга используют его, поэтому это один из самых распространённых веб-API, на который обычные сайты опираются каждый день.
У Canvas есть и побочный эффект. Когда браузер рисует текст или фигуры на холсте, точные пиксели зависят от GPU устройства, графического драйвера, отрисовки текста в операционной системе, управления цветом и сглаживания краёв. Два компьютера, выполняющие одни и те же команды рисования, могут вернуть слегка разные данные пикселей, а один и тот же компьютер каждый раз возвращает одни и те же данные. Именно эта повторяемость позволяет использовать результат как сигнал для распознавания браузера.
Исследования слежения зафиксировали это на практике. Princeton Web Census, масштабное измерение миллиона самых посещаемых сайтов, нашёл скрипты отпечатка Canvas более чем на 14 000 из них. Эти цифры принадлежат указанному исследованию и не являются измерениями BotBrowser.
Отпечаток Canvas не требует запроса разрешения, ничего не сохраняет на устройстве и ничего не показывает посетителю. В браузерах нет встроенной настройки, которая отключала бы этот сигнал, а пиксели создаются независимо от того, видит ли посетитель какой-либо элемент страницы, поэтому сигнал сохраняется, пока что-то не изменит способ получения вывода Canvas. Разделы ниже рассказывают, как возникает сигнал, почему привычные средства приватности его не меняют, какими способами можно обращаться с выводом Canvas и как проверить его стабильность во время авторизованного теста.
Что измеряет отпечаток Canvas
Скрипту отпечатка само изображение не интересно. Типичный процесс сбора состоит из пяти коротких шагов:
- Скрипт выполняется на странице или во встроенном фрейме, часто в составе рекламного или аналитического компонента.
- Он создаёт холст и рисует фиксированный тестовый узор: текст несколькими шрифтами, градиенты, пересекающиеся фигуры и полупрозрачные цвета.
- Он считывает пиксели обратно через
toDataURLилиgetImageData. - Он сжимает данные пикселей в короткое итоговое значение.
- Он отправляет это значение на сервер вместе с другими сигналами браузера, где оно сопоставляется с прошлыми визитами.
Итоговое значение полезно трекеру по трём причинам. Оно не меняется после удаления cookie, не меняется за другим IP-адресом и его дёшево собирать на любой странице. Сайт, который снова видит то же значение, может связать визиты, а трекер, присутствующий на многих сайтах, может связать визиты на не связанных между собой доменах.
Canvas редко используют отдельно. Скрипты сочетают его со сведениями о рендерере WebGL, установленными шрифтами, параметрами экрана, часовым поясом и языком. Вместе сигналы, каждый из которых разделяют многие браузеры, всё равно могут выделить одно устройство. Canvas вносит ту часть, что приходит из графического и текстового тракта отрисовки, а эту часть трудно изменить правкой других настроек.
Считывание пикселей само по себе тоже обычная операция. Диаграммы, фоторедакторы, захват подписи и некоторые CAPTCHA читают пиксели по рядовым причинам, поэтому сам вызов подозрений не вызывает. Проблема в скрытом тестовом узоре, единственная цель которого создать идентификатор. Документация по Canvas API на MDN и раздел canvas стандарта HTML описывают сам интерфейс, и оба указаны в источниках ниже.
Те, кто проверяет сайт на предмет отпечатков, обычно ищут узнаваемый рисунок поведения, а не один вызов API. Холст, который создан, но никогда не добавляется на страницу, небольшой фиксированный размер, фраза с множеством разных букв, пересекающиеся цветные фигуры и немедленное считывание с последующей отправкой по сети считаются типичными признаками. Ни один из них сам по себе не доказывает намерение, а легитимная диаграмма может разделять некоторые из них, поэтому проверяющий оценивает их вместе с тем, что скрипт делает с результатом.
Почему один и тот же рисунок различается на разных устройствах
Для воспроизводимого сравнения зафиксируйте рецепт: width и height canvas, строку и шрифт для fillText(), затем байты из getImageData(0, 0, width, height). Изменение любого из этих входов не доказывает смену графического стека.
Спецификации описывают смысл вызова рисования, а не точное значение каждого выходного пикселя, поэтому у каждой платформы есть простор для различий. На практике вклад вносят несколько уровней тракта отрисовки:
- Растеризация шрифтов. Windows, macOS и Linux используют собственные стеки отрисовки текста с разной формой глифов, хинтингом и сглаживанием краёв.
- GPU и драйвер. Градиенты, смешивание и композиция проходят через графическое оборудование и драйверы, которые могут различаться в последних битах каждого цветового канала.
- Управление цветом. Операционные системы применяют разные цветовые профили и обработку гаммы, что сдвигает значения внутри градиентов и полупрозрачных фигур.
- Сглаживание. Сглаживание краёв зависит от платформы, версии драйвера и системных настроек. Различия не видны глазу, но присутствуют в данных пикселей.
- Арифметика с плавающей точкой. Кривые и геометрические операции на разном оборудовании могут округляться по-разному, из-за чего меняются несколько пикселей вдоль краёв.
Шрифты добавляют ещё один уровень. Когда скрипт запрашивает шрифт, которого нет в системе, платформа подставляет шрифт по умолчанию, и этот выбор зависит от операционной системы и установленных в ней шрифтов. Поэтому один и тот же текст, нарисованный шрифтом с тем же именем, может дать разные глифы в двух системах, и именно поэтому шрифты считаются самостоятельной поверхностью отпечатка.
Каждое различие крошечное, но отпечатку достаточно, чтобы отличался один пиксель. Такое сочетание стабильно на одной машине и меняется от машины к машине. Оно также переживает перезапуск браузера, очистку кэша и открытие приватного окна, потому что ни одно из этих действий не меняет графический стек под ними.
Та же логика работает и в обратную сторону. Две машины с одной версией операционной системы, тем же GPU, драйвером и шрифтами могут вернуть одинаковый вывод, так что один Canvas сужает круг, а не называет конкретное устройство. Поэтому трекеры сочетают его с другими сигналами, и поэтому защита, которая смотрит только на Canvas, оставляет остальную часть сочетания нетронутой.
Поэтому Canvas тесно связан с остальным профилем устройства. Браузер, который сообщает GPU Apple и пользовательский агент Mac, но выдаёт вывод Canvas, типичный для отрисовки текста в Linux, внутренне противоречив, а согласованность сигналов как раз то, на что смотрит каждый, кто анализирует отпечатки.
Почему VPN, приватный режим и расширения не решают задачу
Граница видна в API: VPN меняет адреса, доступные RTCPeerConnection или HTTP, а Canvas-идентификация читает пиксели через getImageData() либо toDataURL(). Очистка localStorage или cookie меняет сохранённое состояние, а не bitmap, возвращаемый этими вызовами.
Каждое привычное средство приватности действует на другом уровне, чем тот, из которого Canvas берёт данные.
VPN и прокси. VPN или прокси меняет сетевой адрес, который видит сайт. Вывод Canvas создаётся внутри браузера на основе локальной отрисовки и никогда не проходит по сетевому пути, поэтому два устройства за одним VPN по-прежнему возвращают каждое свой вывод Canvas.
Приватный режим. Приватные окна удаляют cookie, историю и хранилище сайта по завершении сеанса. Они не меняют тракт отрисовки, так что вывод Canvas в приватном окне совпадает с выводом в обычном. Руководство по приватному просмотру объясняет, что эти режимы меняют, а что нет.
Расширения, блокирующие Canvas. Блокировка считывания приводит к тому, что вызовы завершаются ошибкой или возвращают пустые данные. Очень мало реальных браузеров ведут себя так, поэтому сама блокировка может выделяться, а страницы, использующие Canvas в законных целях, могут перестать работать.
Расширения, добавляющие случайный шум. Случайный шум даёт новое значение при каждой загрузке. Это не позволяет получить один стабильный идентификатор, но значение, меняющееся при каждом визите, тоже необычно, а шум, добавленный на уровне скриптов, может не напоминать естественный разброс между реальными устройствами.
Расширения, возвращающие поддельные данные. Подставленные пиксели могут ломать диаграммы, карты и CAPTCHA, и они часто расходятся с GPU, шрифтами и операционной системой, о которых тот же браузер сообщает в других местах.
Встроенная рандомизация. Некоторые браузеры, в том числе Brave, добавляют небольшие случайные изменения к выводу Canvas для каждого сайта. Это лучше блокировки, но результат всё равно может не сходиться с сигналами GPU, шрифтов и операционной системы, которые сообщает тот же браузер, а каждая реализация сама решает, какие операции Canvas она охватывает.
Неравные результаты разных средств. Ни одно средство не меняет все уровни. VPN меняет сетевой адрес, но не пиксели, приватный режим меняет хранилище, но не пиксели, а расширение меняет то, что видит скрипт, не меняя способ отрисовки страницы. Каждое решает одну задачу и оставляет сигнал Canvas как есть, поэтому долговременный ответ должен затрагивать сами пиксели.
Запросы разрешения. Tor Browser спрашивает, прежде чем сайт сможет прочитать данные изображения Canvas. Это делает считывание заметным, но оставляет решение посетителю, а отклонённый запрос может сломать страницу, которая его сделала.
Четыре способа обращения с выводом Canvas
Зафиксируйте выбор двумя параметрами: --bot-noise-canvas=true включает политику на уровне рендеринга, а --bot-noise-seed=42 задаёт воспроизводимый рисунок шума. Не сравнивайте запуск без указанного seed с запуском с фиксированным seed.
Подходы различаются тем, чем они жертвуют. Сравнить их помогают два вопроса: остаётся ли вывод стабильным при той же настройке и остаётся ли он согласованным со всем остальным, о чём сообщает браузер?
- Блокировка. Вывод стабилен, потому что он всегда пуст, но он не согласуется с обычным браузером и, скорее всего, ломает страницы, которым нужен Canvas.
- Случайный шум. Вывод различается при каждой загрузке или для каждого источника. Это ограничивает связывание в пределах области шума, но не даёт повторяемого результата для тестов и может не совпадать с другими сигналами.
- Поддельные данные. Фиксированное подставное значение повторяемо, но не связано с тем, что страница на самом деле нарисовала, поэтому функции, зависящие от рисунка, и другие сигналы могут ему противоречить.
- Детерминированный вывод по профилю. Вывод Canvas следует загруженному профилю и фиксированному зерну шума, поэтому один и тот же профиль и то же зерно всегда дают один результат, а другой профиль или другое зерно дают иной.
Последний вариант важен для авторизованного тестирования и исследований приватности, потому что делает поведение Canvas воспроизводимым. Если тест показывает изменение вывода, причина в изменённом профиле или зерне, а не в остаточном шуме предыдущего запуска.
Какой вариант подходит, зависит от цели. Блокировка подходит для жёстко ограниченной среды только для чтения, где сломанные страницы допустимы. Случайный шум подходит для повседневного просмотра, где нужно лишь не быть связанным между сайтами. Детерминированный вывод подходит для работы, где результат нужно повторять и объяснять, например для проверок регрессии на сайте, которым вы управляете, или для исследования, сравнивающего одну конфигурацию с другой.
Детерминированность не означает, что сигнал исчезает. Canvas лишь один из многих сигналов, и стабильное значение, которое расходится с WebGL, шрифтами, часовым поясом, региональными настройками или сетевым расположением, всё равно может выглядеть противоречиво. Поэтому проверки в последнем разделе выходят за рамки одного Canvas.
Как BotBrowser обращается с Canvas
Документация BotBrowser по Canvas описывает защиту считывания Canvas на основе профиля. Когда профиль загружен, BotBrowser применяет детерминированный шум к выводу Canvas 2D на уровне отрисовки, а не через внедрение JavaScript, и документация указывает, что это охватывает считывание пикселей и измерение текста. Для описанного выше сценария важны четыре задокументированных поведения:
- Шум Canvas включён по умолчанию, и его можно задать явно через
--bot-noise-canvas=trueили--bot-noise-canvas=false. --bot-noise-seedвыбирает конкретный воспроизводимый узор шума. Каждое зерно даёт уникальный, но стабильный вывод Canvas, и то же зерно действует и на другие поверхности, такие как WebGL, WebGPU и метрики текста.- При загруженном профиле BotBrowser использует встроенные библиотеки шрифтов и собственную отрисовку, чтобы сравнивать вывод Canvas на разных хостах при документированных условиях профиля, зерна, экрана и графики; одинаковый вывод на всех хостах и графических стеках не гарантируется.
- BotBrowser 150 сохраняет защиту Canvas 2D для стандартных и широкогамутных цветовых пространств, включая
display-p3.
Минимальный запуск, фиксирующий и профиль, и зерно, выглядит так:
chromium-browser --bot-profile="path/to/profile.enc" --bot-noise-seed=42
Поскольку каждое зерно даёт собственный стабильный результат, команда, запускающая несколько сеансов, может назначить каждому сеансу своё зерно. Тогда сеансы остаются различимыми между собой, но точно повторяются при повторном использовании зерна, а именно это свойство нужно тесту регрессии.
Держите настройку простой. Второе средство, также изменяющее вывод Canvas, например расширение, затрудняет интерпретацию результатов, потому что одни и те же пиксели формируют уже два уровня.
Для проверки документация CanvasLab описывает запись через --bot-canvas-record-file вызовов Canvas 2D, WebGL, WebGL2 и WebGPU, которые делает страница, чтобы команда увидела, что страница на самом деле рисует и читает, прежде чем решать, что тестировать.
Проверка стабильности и разбор расхождений
Полезная проверка состоит из трёх шагов и не требует собственного кода сбора. Запускайте её только на страницах и системах, которые вы вправе тестировать.
- Запустите браузер с профилем и фиксированным
--bot-noise-seed, откройте публичную страницу для проверки отпечатков и запишите сообщённый вывод Canvas. - Перезагрузите страницу, затем закройте и снова запустите сеанс с тем же профилем и тем же зерном. Вывод должен совпасть с первым запуском.
- Смените зерно или профиль. Вывод должен измениться.
Держите область теста узкой и документированной. Используйте страницы, которые принадлежат вам или на тестирование которых у вас есть письменное разрешение, и считайте результат свидетельством только о выводе Canvas, а не вердиктом о другой поверхности отпечатка или о реакции конкретного сайта.
Записывайте настройку рядом с каждым результатом. Версии BotBrowser, файла профиля, значения зерна, операционной системы хоста и того, был ли запуск без интерфейса или с интерфейсом, достаточно, чтобы позднейший запуск можно было сравнить честно. Без такой записи различие между двумя запусками невозможно связать с причиной.
Если результат не соответствует ожиданиям, документация BotBrowser указывает короткий список причин:
- Вывод меняется между сеансами с тем же профилем. Без фиксированного зерна шум по замыслу меняется от сеанса к сеансу, поэтому убедитесь, что значение
--bot-noise-seedодно и то же. - Вывод различается между запусками без интерфейса и с интерфейсом. Убедитесь, что в обоих случаях заданы
--bot-noise-canvas=trueи один профиль. - Вывод похож на необработанный вывод системы. Убедитесь, что профиль загрузился правильно, и прочитайте сообщения при запуске.
- Вывод различается на другой операционной системе хоста. Перед интерпретацией проверьте профиль, зерно, экран, графический backend и шрифты; профиль делает сравнение воспроизводимым, но не гарантирует одинаковый вывод на всех хостах.
- Широкогамутный Canvas ведёт себя иначе, чем стандартный. Используйте BotBrowser 150.0.7871.46 или новее с подходящим пакетом профиля.
Читайте первый результат внимательно. Один запуск показывает лишь то, что вывод существует. Сравнение между перезагрузками, перезапусками, зёрнами и профилями показывает, ведёт ли себя вывод как задумано, а отсутствие изменения на третьем шаге так же информативно, как несовпадение на втором.
Затем проверьте то, что Canvas не охватывает. Сравните значения рендерера WebGL, установленные шрифты, часовой пояс, региональные настройки и сетевое расположение с тем же профилем, потому что стабильный результат Canvas рядом с часовым поясом или языком, не совпадающими с профилем, всё равно даёт противоречивую картину. Статьи об отпечатке WebGL, отпечатке шрифтов и воспроизводимости зерна шума охватывают эти соседние сигналы.
BotBrowser применяет детерминированный шум Canvas 2D на основе профиля на уровне отрисовки, воспроизводимый по --bot-noise-seed при объявленных условиях, чтобы команда могла сравнивать считывание Canvas в описанном сценарии авторизованного тестирования и исследований приватности. BotBrowser не может гарантировать анонимность или то, что сайт не определит, не отследит и не заблокирует посетителя; он также не управляет скриптами сбора Canvas на сайте или кластеризацией устройств на сервере. Для воспроизводимого сравнения между хостами нужно сохранять одинаковыми профиль, зерно, экран, графический backend и шрифты; это не означает, что любой графический стек даст идентичный вывод. Это не заменяет согласование сигналов WebGL, шрифтов, часового пояса, региональных настроек и прокси с тем же профилем.
Для более подробного разбора см. Fingerprinting измерения текста: субпиксельное отслеживание.
Итог
В авторизованном сравнении зафиксируйте рецепт рисунка и укажите профиль, --bot-noise-seed, дисплей, шрифты и графический backend рядом с чтением пикселей. Неожиданное различие сначала является вопросом конфигурации; ни стабильный, ни изменившийся digest не доказывает анонимность или решение удалённого сайта.
Источники
Эта статья входит в руководство: Что такое отпечаток браузера?
Похожие статьи
Аудио-отпечатки: как AudioContext отслеживает вас
ОтпечаткиДетерминированный режим: воспроизводимые отпечатки
ОтпечаткиFingerprinting измерения текста: субпиксельное отслеживание
Отпечаткиwebgl_debug_renderer_info: что GPU раскрывает страницам
ОтпечаткиЧто такое отпечаток браузера?
Отпечаткиperformance.now: разрешение таймера и отпечаток браузера
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.