CSS-фингерпринтинг: как стили отслеживают вас
Как CSS-медиазапросы вроде color-gamut и prefers-color-scheme создают сигналы отпечатка и как сохранить согласованность значений CSS и JavaScript.
BotBrowser Team
Нужна поддерживаемая продуктовая документация?
У этой статьи есть соответствующая страница в центре документации. Используйте docs для каноничного сценария настройки, актуальных флагов и долгосрочной справки.
CSS обычно описывают как язык оформления, а не как поверхность для отслеживания. Тем не менее медиазапросы позволяют таблице стилей спросить у браузера об экране, настройках человека и доступных устройствах ввода, а ответы различаются у разных групп пользователей. Такие возможности, как prefers-color-scheme, prefers-reduced-motion, color-gamut, resolution, pointer и hover, раскрывают по небольшой детали конфигурации устройства. Таблица стилей может прочитать эти детали без единой строки JavaScript, поэтому средства приватности, ориентированные на скрипты, порой упускают этот путь.
Смотреть видео
Это англоязычное видео показывает, как таблица стилей может сообщить серверу о тёмной теме посетителя без запуска скрипта, а затем сравнивает ответ таблицы стилей со значением, которое читает скрипт, на локальной лабораторной странице и в официальном Chrome на двух машинах. Проверка не использует профиль BotBrowser и не доказывает идентичность, анонимность, доступ или решение удалённого сайта. Звук на английском языке.
Полезный вопрос не в том, идентифицирует ли человека одна возможность. Нет, не идентифицирует. Вопрос в том, совпадают ли значения, которые страница видит через CSS, со значениями, которые она видит через JavaScript, и остаются ли они стабильными для той конфигурации, которую вы хотите предъявлять. В разделах ниже описано, какие медиавозможности задействованы, как условная загрузка раскрывает их без скриптов, почему частичная защита оставляет пробелы, как проверять согласованность, что могут сделать авторы сайтов и что BotBrowser охватывает, а что нет.
BotBrowser может согласовать CSS-медиазапросы и связанные значения экрана с загруженным профилем, включая явно заданную цветовую схему и значения экрана из профиля. Он не управляет тем, что таблица стилей сайта запрашивает или записывает, не делает сессию анонимной и не заменяет настройки доступности. Поэтому статья посвящена согласованности профиля и ее ограничениям, а не обещанию анонимности.
Кратко
Медиазапросы CSS раскрывают малую энтропию экрана, предпочтений и ввода, а условная загрузка ресурсов может показать их без JavaScript. Используйте один источник на основе профиля для CSS и JavaScript, проверяйте повторные сессии и воспринимайте согласование BotBrowser как средство согласованности, а не гарантию анонимности.
Содержание
- Смотреть видео
- Какие медиавозможности несут сигнал
- Как таблица стилей читает значения без JavaScript
- Почему привычные способы защиты оставляют пробелы
- Проверка согласованности одного профиля
- Что могут сделать авторы сайтов
- Что охватывает BotBrowser и что остается за его рамками
- Часто задаваемые вопросы
Какие медиавозможности несут сигнал
Медиазапросы CSS проверяют условия среды, в которой отображается страница. Возможности, наиболее важные для фингерпринтинга, делятся на четыре группы.
- Экран.
resolution,color,color-index,color-gamutиmonochromeописывают плотность пикселей, глубину цвета и диапазон цветов, которые способен показать экран. - Предпочтения.
prefers-color-scheme,prefers-reduced-motion,prefers-contrast,prefers-reduced-transparencyиforced-colorsраскрывают выбор, сделанный в настройках операционной системы или браузера. - Окно и экран.
width,height,aspect-ratioиorientationописывают окно, а более старыеdevice-widthиdevice-heightописывают экран. - Взаимодействие.
hover,any-hover,pointerиany-pointerсообщают странице, может ли основное устройство ввода наводиться на элемент и насколько оно точно.
Каждое значение откуда-то берется. Аппаратная часть монитора задает цветовой охват, глубину и разрешение. Настройки операционной системы определяют тёмный режим, контраст и предпочтения по анимации. Конфигурация браузера может переопределять систему, а режимы приватного просмотра способны менять отдельные значения. Важен и тип устройства: сенсорные устройства обычно сообщают pointer: coarse и hover: none, а настольные компьютеры сообщают pointer: fine и hover: hover.
Что это раскрывает? Спецификация W3C Media Queries Level 5 признает, что возможности пользовательских предпочтений могут вносить вклад в фингерпринтинг. Каждая возможность по отдельности имеет низкую энтропию: обычно это логическое значение или несколько вариантов, чаще всего от одного до трех бит. В сочетании картина меняется. Исследование TU Graz сообщило, что одни лишь медиавозможности CSS отличали примерно трех из десяти пользователей, когда одновременно запрашивали более пятнадцати возможностей, а суммарную энтропию оценивали в 10-15 бит при благоприятных условиях. Воспринимайте эти цифры как опубликованные диапазоны, а не как гарантии: они зависят от измеряемой группы людей и от того, сколько возможностей запрашивает страница.
Приблизительный расчет показывает, почему важны сочетания. Семь возможностей по два или три значения каждая уже дают несколько сотен различных комбинаций. Реальных комбинаций меньше, потому что возможности коррелируют: у телефона с сенсорным указателем почти никогда нет наведения, а у настольного компьютера с точным указателем оно почти всегда есть. Эффективная информация поэтому меньше простого произведения, но все равно больше, чем подсказывает любая отдельная возможность.
Не все значения весят одинаково. Распространенное значение, например светлая тема на обычном настольном экране, помещает посетителя в очень большую группу и мало говорит сайту. Редкое значение, например активный режим forced-colors, охват rec2020 или запрос на сниженную прозрачность, помещает посетителя в гораздо меньшую группу. Новые возможности вроде dynamic-range, prefers-reduced-data и inverted-colors добавляют новые измерения, а каждая возможность, которую браузер добавляет в платформу, становится ещё одним значением, о котором может спросить таблица стилей. Поэтому необычная комбинация, как правило, информативнее обычной, а несогласованная комбинация информативнее всех.
Как таблица стилей читает значения без JavaScript
Скрипт может проверить медиазапрос напрямую через window.matchMedia(), который сообщает, выполняется ли условие в данный момент. Именно этот путь отслеживает большинство средств приватности.
const dark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const dense = window.matchMedia('(min-resolution: 2dppx)').matches;
const wide = window.matchMedia('(color-gamut: p3)').matches;
Второй путь вообще не требует скрипта. Это условная загрузка ресурсов, когда правило внутри блока @media ссылается на URL.
@media (prefers-color-scheme: dark) {
.tracker {
background-image: url('https://stats.example.com/dark');
}
}
@media (prefers-color-scheme: light) {
.tracker {
background-image: url('https://stats.example.com/light');
}
}
Браузер запрашивает только то изображение, условие которого выполнено, поэтому сервер узнает цветовую схему посетителя по тому, какой URL пришёл. Повторяя шаблон с большим числом условий, одна таблица стилей собирает много двоичных ответов: тёмная или светлая схема, высокая или обычная плотность, точный или сенсорный указатель. Поскольку сведения идут в обычном запросе, даже те, кто полностью блокирует JavaScript, могут быть частично идентифицированы таким способом.
Условия можно и объединять. Правило вроде @media (prefers-color-scheme: dark) and (min-resolution: 2dppx) срабатывает только при выполнении обеих частей, поэтому таблица стилей может запрашивать один URL на сочетание, а не по одному на возможность. Число запросов остается скромным, а посетители при этом разделяются сразу по нескольким возможностям, и одно расхождение между двумя путями может повлиять на результат многих правил.
Стоит помнить о двух свойствах этого пути. Во-первых, медиазапросы пересчитываются при изменении среды, поэтому переключение на тёмный режим посреди визита вызывает новый запрос, и изменение становится видно не только при загрузке, но и со временем. Во-вторых, возможности предпочтений обычно общие для всех фреймов страницы, а возможности окна следуют размеру каждого фрейма, поэтому значения могут по законным причинам различаться между документом и встроенным фреймом.
Поэтому два пути обязаны совпадать. Таблица стилей и скрипт читают одну и ту же среду, и сайт может сравнить, что сообщает каждый из них. Если matchMedia('(prefers-color-scheme: dark)') говорит одно, а ресурс, загруженный таблицей стилей, другое, или если screen.colorDepth и devicePixelRatio противоречат CSS-возможностям color и resolution, то само расхождение является сигналом, каковы бы ни были отдельные значения.
Медиазапросы не единственная часть CSS, отражающая платформу. Правила @supports показывают, какие свойства и значения реализует браузер, ключевые слова системных цветов разрешаются в цвета, заданные темой операционной системы, а ключевые слова шрифтов вроде system-ui разрешаются в шрифт платформы. Таблица стилей может использовать любое из них, чтобы узнать, какая операционная система или семейство браузеров породили страницу, и каждое из них по той же причине должно оставаться согласованным с остальной конфигурацией. Профиль, описывающий одну платформу, при том что системные цвета или системный шрифт следуют другой, создает такое же расхождение, как медиазапрос, противоречащий matchMedia().
Почему привычные способы защиты оставляют пробелы
Несколько знакомых подходов решают часть задачи и оставляют остальное.
- Расширения, оборачивающие
matchMedia(), меняют то, что видят скрипты, но таблица стилей по-прежнему вычисляет правила@mediaпо реальному экрану и реальным настройкам. Страница с условной загрузкой получает истинное значение из CSS и изменённое значение из скрипта, так что несогласованность создает само расширение. - Отключение CSS непрактично, потому что большинство сайтов без него просто непригодны для использования.
- Стандартизированные предпочтения, например постоянно светлая тема, отсутствие сниженной анимации и охват sRGB, уменьшают разброс, но создают приметную группу. Браузер, сообщающий значение по умолчанию для каждого предпочтения, может выделяться среди людей с разными настройками.
- Tor Browser стандартизирует многие значения у своих пользователей, что дает большую общую группу, но эта группа узнаваема как Tor Browser.
Встроенные в браузеры режимы сопротивления следуют похожей схеме. Firefox предлагает параметр защиты от фингерпринтинга, который сообщает фиксированные значения для ряда возможностей предпочтений, а это тот же компромисс, что и при стандартизации: разброс внутри группы намного меньше, но группа узнаваема по своим фиксированным значениям. Ни один из этих подходов не плох для своей аудитории. Они просто отвечают на другой вопрос, чем тот, что поставлен здесь: как сохранить выбранную конфигурацию согласованной на всех путях, которыми может воспользоваться страница.
Остается требование согласованности, а не маскировки. Медиавозможности CSS, matchMedia() и связанные значения вроде screen.colorDepth и devicePixelRatio должны происходить из одного источника, и этот источник должен описывать целостное устройство. Политика соотношения пикселей устройства объясняет, почему плотность относится к числу самых часто сравниваемых значений, а руководство по фингерпринтингу экрана и окна охватывает значения размеров, которые стоят рядом с ней.
Проверка согласованности одного профиля
Полезная проверка сравнивает одну и ту же возможность по двум путям для одного профиля, а затем повторяет сравнение в более поздней сессии.
- Цветовая схема. Откройте страницу с тёмной темой и убедитесь, что отображаемая тема и
matchMedia('(prefers-color-scheme: dark)').matchesсовпадают друг с другом и с заданным вами значением. - Разрешение. Сравните
window.devicePixelRatioс результатомmatchMedia('(min-resolution: 2dppx)'). Оба должны описывать одну и ту же плотность. - Глубина цвета и охват. Сравните
screen.colorDepthс CSS-возможностьюcolorи проверьтеcolor-gamutотносительно экрана, который представляет профиль. - Указатель и hover. Убедитесь, что
pointerиhoverсоответствуют основному устройству ввода, объявленному в профиле, которое не всегда совпадает с форм-фактором: профиль телефона обычно сообщает coarse без hover, а профиль рабочего стола всё ещё может сообщать coarse или отсутствие hover, если объявленный ввод является сенсорным экраном. - Стабильность. Повторите те же проверки в нескольких сессиях с тем же профилем. Значения должны каждый раз быть одинаковыми.
Проверяйте и путь через таблицу стилей, и путь через скрипт. Небольшая локальная страница, у которой правила @media меняют цвет видимого элемента, показывает, что видит CSS, а условная загрузка читает те же значения. Если отображение и результат скрипта расходятся, этот разрыв нужно устранить в первую очередь, прежде чем настраивать что-либо ещё.
Тёмный режим также меняет внешний вид страниц. Если вы делаете снимки экрана или сравниваете макеты между запусками, задавайте цветовую схему явно, чтобы результаты оставались сопоставимыми. Незаданное значение, следующее за хост-машиной, может отличаться между ноутбуком и сервером, и различие проявится как визуальное изменение, не связанное со страницей.
Включите в проверку встроенные фреймы и стили печати. Фрейм вычисляет собственные правила @media, поэтому тестовая страница со вторым встроенным документом показывает, совпадают ли возможности предпочтений между фреймами, тогда как возможности окна следуют размеру каждого фрейма. Стили печати используют тип носителя print, который страница может вызвать намеренно, поэтому таблица стилей с блоком @media print служит ещё одним местом, где можно прочитать значения, связанные с отображением. Считайте это той же проверкой, повторенной в других контекстах, а не отдельными проблемами.
Когда проверка не проходит, меняйте что-то одно за раз. Начните с базового запуска, где загружен только профиль, запишите значения по обоим путям, затем добавьте единственный параметр, например цветовую схему или источник экрана, и сравните снова. Сохраните итоговую команду запуска в заметках, чтобы последующая сессия смогла повторить её в точности. Если цветовая схема не совпадает с ожидаемой, задайте её явно, а не полагайтесь на значение по умолчанию. Если проверка возможности или системный цвет указывает на иную платформу, чем вы планировали, сначала убедитесь, что загруженный профиль описывает нужную платформу, ведь доступность возможностей следует за профилем.
Условие прохождения для каждой пары
| Пара для сравнения | Проходит, когда |
|---|---|
prefers-color-scheme против matchMedia | Оба сообщают одну схему при каждой загрузке |
devicePixelRatio против min-resolution | Отсечка в запросе совпадает с сообщённым соотношением |
screen.colorDepth против color | screen.colorDepth не меньше утроенного color |
pointer / hover против ввода | Оба соответствуют основному устройству ввода, описанному в профиле |
Список выше говорит, на что смотреть; эта таблица говорит, когда взгляд отвечает на вопрос. Без записанного условия проверяющий сравнивает два значения на глаз и принимает ту пару, которая выглядит правдоподобно, и именно так расхождение переживает несколько сеансов.
Запишите условие до того, как прочитаете любое из двух значений, и фиксируйте результат как истину или ложь, а не как пару чисел. Логическая строка и делает два сеанса сопоставимыми: те же четыре строки, тот же ожидаемый результат и diff, который показывает, какая строка перевернулась.
Следите за единицами. devicePixelRatio является соотношением вроде 2, тогда как min-resolution принимает dppx или dpi, поэтому (min-resolution: 2dppx) и (min-resolution: 192dpi) описывают одну плотность, записанную двумя способами. Сравнение соотношения со значением в dpi даёт расхождение, которое является ошибкой единиц, а не проблемой профиля.
Следите и за направлением сравнения. (min-resolution: 2dppx) спрашивает, не меньше ли плотность двух, поэтому профиль с соотношением ровно 2 проходит, а 1.5 не проходит; это правильный результат, а не дефект. Запишите точный запрос, чтобы следующий сеанс не прочитал изменённый запрос как изменённый экран.
Две строки заслуживают особого внимания, и ни одна из них не является простым равенством. CSSOM View требует, чтобы screen.colorDepth было не меньше утроенного значения CSS color, потому что первое считает биты на пиксель, а второе биты на цветовую компоненту; равенство не требуется и не гарантируется, поэтому сравнение в расчёте на совпадение сообщает о дефекте там, где его нет. Вторая строка про указатель: Media Queries Level 5 определяет pointer и hover по основному указывающему устройству, а не по форм-фактору, и прямо допускает сенсорный экран как основной ввод на настольной машине, поэтому профиль рабочего стола может сообщать pointer: coarse или hover: none и оставаться согласованным. Материал об управлении цветом разбирает смежный случай, когда заявление об охвате опережает описываемый экран.
Что могут сделать авторы сайтов
У авторов сайтов своя роль во всем этом. Запросы @media существуют для того, чтобы оформление могло подстраиваться, и эту цель стоит защищать. Несколько привычек помогают отделить её от сбора данных.
- Используйте медиавозможности для изменения оформления и не привязывайте к ним сетевые запросы. Другой фон для тёмного режима обычно решается одним ресурсом и пользовательскими свойствами CSS или элементом
<picture>, без отдельных URL для каждой возможности. - Отдавайте любой ресурс, зависящий от медиаусловия, со своего собственного источника. Запрос к стороннему хосту, который различается по экрану или предпочтению, дает этому хосту сигнал, которым ваши посетители делиться не соглашались.
- Не записывайте, какой условный ресурс загрузил посетитель, если в этом нет необходимости. Если записываете, укажите это в уведомлении о конфиденциальности и храните данные недолго.
- Уважайте предпочтение, выбранное человеком. Сниженная анимация, контраст и принудительные цвета относятся к настройкам доступности, а статья о предпочтениях медиазапросов и контроле пользователя показывает, как их учитывать, сохраняя видимый способ выбрать оформление.
Эти привычки почти ничего не стоят и сокращают объем данных об экране и предпочтениях, покидающих страницу.
Проверка со стороны автора проста. Откройте панель сети в браузере, переключите цветовую схему или параметр сниженной анимации в операционной системе и посмотрите, какие запросы меняются. Любой запрос, зависящий от предпочтения, заслуживает повторного взгляда: спросите себя, нужен ли он дизайну, возможен ли тот же результат с одним ресурсом и принадлежит ли принимающий хост вам. Повторяйте эту проверку при добавлении таблицы стилей или стороннего виджета, потому что встроенный компонент может ввести условные запросы, которых остальной сайт никогда не использовал.
Настройки доступности требуют особой осторожности с обеих сторон. Сниженная анимация, высокий контраст и принудительные цвета существуют потому, что некоторым людям неудобно пользоваться страницей без них. Конфигурация приватности, которая переопределяет их, чтобы походить на всех остальных, может затруднить работу с сайтами для человека за клавиатурой, а сайт, который их игнорирует, напрямую вредит этим людям. Когда браузер, в котором вы тестируете, сообщает значения, отличные от ваших собственных настроек, помните, что различие действует только в этой сессии, а ваши реальные предпочтения по-прежнему относятся к браузеру, которым вы пользуетесь каждый день.
Что охватывает BotBrowser и что остается за его рамками
Документация BotBrowser по CSS Signal Consistency описывает соответствующие параметры. Базовый запуск загружает профиль, а цветовую схему и источник экрана можно задать явно.
chrome --bot-profile="path/to/profile.enc" \
--bot-color-scheme=dark \
--bot-screen=profile
--bot-color-scheme принимает light или dark. --bot-screen=profile использует свойства экрана, заданные профилем, такие как глубина цвета и размеры, вместо значений экрана хост-машины. Оба параметра необязательны.
Сначала выберите профиль, потому что CSS-значения сессии происходят из него. Профиль описывает одно устройство, поэтому берите такой, платформа и тип устройства которого соответствуют вашей работе, и подтверждайте указатель и наведение проверками выше. Последующее изменение цветовой схемы или источника экрана подстраивает оформление внутри этого профиля. Оно не превращает настольный профиль в телефон.
BotBrowser согласует медиазначения CSS и связанные значения экрана с загруженным профилем: цветовая схема следует за профилем и --bot-color-scheme, а глубина цвета и размеры экрана следуют за профилем. Поэтому @media и matchMedia() сообщают значения профиля, а не хост-машины. Это помогает проверить согласованность двух путей и повторяемость ответа между сессиями. Ограничения не менее важны. BotBrowser не управляет запросами или записью таблицы стилей сайта, не делает сессию анонимной или несвязываемой и не заменяет ваши настройки доступности, например сниженную анимацию или контраст.
Часто задаваемые вопросы
Идентифицирует ли человека одна возможность CSS?
Нет. Отдельные медиавозможности обычно дают мало информации; риск возникает из сочетаний и противоречий между CSS и JavaScript.
Нужно ли стандартизировать все предпочтения?
Не обязательно. Фиксированные значения уменьшают разброс, но могут создать узнаваемую группу и переопределить настройки доступности.
Что записывать во время проверки согласованности?
Запишите профиль, явные параметры запуска, результат CSS, результат скрипта и дату сессии, чтобы повторить сравнение позже.
Практическое заключение
Для воспроизводимой проверки выберите согласованный профиль, при необходимости явно задайте цветовую схему или источник экрана, сравните CSS и JavaScript на одной тестовой странице и повторите проверку в следующих сессиях. Исправьте расхождения до настройки других сигналов фингерпринтинга и помните, что BotBrowser согласует значения, но не управляет сбором данных сайтом и не обеспечивает анонимность.
Источники
Эта статья входит в руководство: Что такое отпечаток браузера?
Похожие статьи
Медиазапросы: уважение пользовательских предпочтений в интерфейсах
ПлатформаУправление цветом CSS и доступность отображения
ОтпечаткиMIME и кодеки: сигналы поддержки медиа в браузере
ОтпечаткиЧто такое отпечаток шрифтов? Согласованность текста между платформами
ОтпечаткиЧто такое отпечаток браузера?
ОтпечаткиDRM-фингерпринтинг: что раскрывают запросы EME и Widevine
Переведите BotBrowser из исследований в продакшн
Используйте эти руководства, чтобы понять модель, а затем перейти к кроссплатформенной валидации, изолированным контекстам и масштабируемому браузерному развертыванию.