вернуться к обзору Больше статей

Отпечаток шрифтов: как вас выдают установленные шрифты

Генерация отпечатка шрифтов...

Ваш список шрифтов собирался годами. Пару сотен положила туда операционная система, Office добавил свои, Adobe докладывала новые с каждым приложением, а декоративный шрифт, установленный ради одного проекта в 2021-м, так никуда и не делся. Любой сайт может прочитать итог за несколько сотен миллисекунд, без всякого запроса разрешения, — и чем длиннее становился этот список, тем меньше шансов, что у кого-то ещё он совпадает с вашим.

Браузеры никогда не давали сайтам возможности просто запросить список шрифтов — именно потому, что он так хорошо идентифицирует. Как выяснилось, это ничему не помешало. Скрипт может не спрашивать, а измерять: ему хватает невидимой строки текста и двух замеров ширины. Виджет на этой странице прогоняет это измерение по 175 шрифтам-кандидатам и показывает, что выдаёт ваш браузер, а заодно — насколько ваш набор распространён среди всех, кто запускал сканирование.

Если коротко: фингерпринтинг шрифтов работает потому, что запросить ваш список шрифтов сайты не могут — и поэтому измеряют его: отрисовывают скрытую тестовую строку, подставляют шрифт-кандидат и смотрят, изменилась ли ширина. Повторите это несколько сотен раз — и получится список, достаточно характерный, чтобы следовать за вами сквозь очистку cookie, окна инкогнито и смену VPN. А половинчатая блокировка этого трюка лишь вручает скрипту более редкий отпечаток.

Как работает фингерпринтинг шрифтов: трюк с измерением

Вот вся техника целиком. Скрипт создаёт невидимый <span> с бессмысленной строкой mmmmmmmmmmlli кеглем 72 пикселя и спрашивает у браузера, какой ширины она получилась в generic-семействе вроде monospace. Затем меняет семейство на "Segoe UI", monospace и читает ширину снова. Если Segoe UI установлен, браузер отрисует его — и ширина сдвинется. Если нет, сработает запасной вариант, и число останется на месте. Один шрифт-кандидат, два замера ширины, ни одного API.

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

Тест ширины — вживую в вашем браузере
font-family: monospace
mmmmmmmmmmlli
font-family: "Segoe UI", monospace
mmmmmmmmmmlli
Измеряем…
Читаем два значения ширины в вашем браузере.
Два замера ширины отвечают на вопрос «есть ли у вас этот шрифт?» для одного кандидата. Виджет на этой странице повторяет это 175 раз; трекинговый скрипт делает то же самое. Измерения выполнены кеглем 72 px — размером, которым настоящие скрипты усиливают различия.

Есть способы и поаккуратнее. document.fonts.check() выдаёт тот же ответ булевым значением за один вызов — в браузерах на Chromium, благодаря причуде, нарушающей спецификацию; Firefox и Safari отвечают true про любой шрифт, какой ни назови, — а измерение текста на canvas и вовсе не трогает DOM. Ровно один вежливый API в этой области у веб-платформы всё же есть: queryLocalFonts() возвращает настоящие имена шрифтов и даже сами файлы шрифтов — после того как пользователь одобрит запрос разрешения. Ни один трекер этот запрос вам ещё ни разу не показывал.

Всё это семейство техник называется перечислением шрифтов (font enumeration), и трекеры — не единственные его клиенты. Антифрод-системы и детекторы ботов гоняют тот же зонд, чтобы проверить, что устройство — то, за что себя выдаёт, поэтому результат следует за вами туда, куда простому рекламщику хода нет: в платёжные процессы, риск-скоринг входа, проверки аккаунтов.

Что выдаёт список установленных шрифтов

Ценен этот список не длиной, а тем, в чём признаётся каждая строчка. Шрифты появляются на машине как побочный эффект всего остального, что вы ставите. Segoe UI означает Windows. Helvetica Neue означает Apple. DejaVu Sans означает Linux. Bahnschrift сужает Windows до версии 10 и новее, а Segoe UI Variable говорит об 11. Minion Pro или Myriad Pro значит, что на этой машине бывал софт Adobe. Windows, установленная под китайский язык, несёт шрифты, которым в американской взяться неоткуда. Ваши шрифты — это летопись того, чем вы пользуетесь и примерно когда вы это поставили:

В чём признаётся ваш список шрифтов
Операционная система
Segoe UI поставляется с Windows
Helvetica Neue поставляется с macOS и iOS
DejaVu Sans поставляется с десктопным Linux
Поколение ОС
Bahnschrift появился в Windows 10, раньше отсутствовал
Segoe UI Variable появился в Windows 11
Установленные программы
Minion Pro устанавливается приложениями Adobe
Myriad Pro устанавливается приложениями Adobe
Проверено вживую в вашем браузере только что — тем же трюком с шириной, которым пользуется трекер. Подсветившиеся строки набрасывают портрет вашей машины: какая ОС, примерно насколько свежая и кое-что из установленного на ней. Никакого запроса разрешения при этом не было.

Это тот же класс утечек, что мы разбирали в статье «Один браузер, пять версий ОС»: ярлыки, которые сообщает браузер, можно переписать, но машина за ними остаётся собой. Поддельный User-Agent под macOS поверх списка шрифтов, полного Segoe и Calibri, — противоречие, которое любой скрипт замечает за миллисекунды.

В исследовании Panopticlick от EFF список шрифтов — тогда его собирали через Flash и Java — нёс 13,9 бита идентифицирующей информации: больше, чем любой другой измеренный сигнал браузерного фингерпринтинга, кроме списка плагинов. Плагины браузеры с тех пор обезвредили — navigator.plugins везде сообщает один и тот же короткий список PDF-просмотрщиков (или вовсе ничего), — а шрифты остаются ровно настолько же измеримыми, как в 2010-м. К тому же список утекает дважды: один раз как список, второй — через canvas-фингерпринтинг, где доступные рендереру шрифты участвуют в решении, какие именно пиксели даст отрисовка на canvas.

И список этот терпелив. Он не меняется от очистки cookie, не меняется в окне инкогнито, а до вашего VPN ему нет ровно никакого дела. Меняется он, когда вы ставите или удаляете программы, — у большинства людей это случается несколько раз в год. По меркам трекинговых идентификаторов это долгий срок годности.

Можно ли защититься от фингерпринтинга шрифтов? Ловушка блокировки

Существуют расширения, обещающие остановить измерение — блокировкой зондов или подмешиванием шума. Проблема та же, на которой по всему этому сайту горят половинчатые подмены: защита встречается реже, чем то, что она прячет.

Десктопный Chrome на Windows, сообщающий лишь горстку веб-безопасных шрифтов, не анонимен — он странен, а странность и есть то, чем кормится фингерпринтинг. Рандомизаторы ещё хуже. Настоящий список шрифтов стабилен месяцами, поэтому список, мутирующий от визита к визиту, помечает вас как одного из немногих владельцев именно этого расширения. А расширения, подделывающие сами числа, делают это, переопределяя те самые функции, которыми страница измеряет. Отсюда вторая проблема: переопределённая встроенная функция при инспекции перестаёт сообщать [native code] — та же примета, что выдаёт stealth-плагины.

Браузеры, защищающиеся от этого всерьёз, делают это целиком. Tor Browser поставляется с собственным набором шрифтов и ограничивает сайты этим фиксированным списком, так что каждый пользователь Tor предъявляет примерно один и тот же короткий набор. Это работает — и заодно сообщает каждому сайту, что у вас Tor. Brave вместо этого прибегает к фарблингу: для каждого сайта и каждой сессии он показывает трекерам шрифты вашей ОС плюс случайную выборку из установленных, так что список, собранный трекером сегодня, тихо расходится с завтрашним, ни разу не выглядя невозможным. Оба подхода работают потому, что вокруг них построен весь браузер, — в отличие от заплатки, воюющей с браузером, внутри которого она сидит.

Что делать на практике

  1. Сначала посмотрите на собственный список. Виджет на этой странице уже измерил ваш браузер. Разверните список шрифтов, чтобы увидеть ровно то, что видит любой сайт, и проверьте, насколько распространён именно ваш набор среди всех сканирований на этом сайте. О наборе, существующем в единственном экземпляре, лучше узнать до того, как это начнёт иметь значение.
  2. Не латайте по кусочкам. Расширение, блокирующее шрифты, поверх во всём остальном обычного браузера делает вас более редким, а не более защищённым. Если хотите такую защиту в повседневном сёрфинге, возьмите браузер, спроектированный вокруг неё, — Brave или Tor — и принимайте их компромиссы осознанно.
  3. Если вы ведёте несколько личностей, список шрифтов — часть личности. Каждому профилю нужны шрифты, согласующиеся с ОС, которую он заявляет, — сессия за сессией. Incogniton даёт каждому профилю собственный список шрифтов и держит его стабильным от сессии к сессии, так что биография, которую читает сайт, принадлежит профилю, а не вашей машине.

Ваши шрифты отвечают на вопросы о вас с тех пор, как у вас появилась эта машина. Виджет выше показывает, что именно они рассказывали, а полное сканирование браузера — что к этому добавляет весь остальной браузер.

Логотип Incogniton

Повысьте уровень своей приватности

Стрелка