Отпечатки

Фингерпринтинг квоты хранилища: размер диска

Как StorageManager.estimate() раскрывает размер диска как сигнал отслеживания, и как контролировать ответы квоты хранилища на уровне движка браузера.

Документация

Нужна поддерживаемая продуктовая документация?

У этой статьи есть соответствующая страница в центре документации. Используйте docs для каноничного сценария настройки, актуальных флагов и долгосрочной справки.

Введение

Storage Manager API был создан для помощи веб-приложениям в понимании того, сколько пространства хранилища доступно для их данных. Через navigator.storage.estimate() веб-сайт может запросить приблизительную квоту хранилища (максимальное доступное пространство) и текущее использование (сколько уже потреблено). Эта информация помогает приложениям принимать решения о стратегиях кеширования, офлайн-хранении данных и о том, стоит ли предложить пользователю освободить место.

API был разработан с хорошими намерениями. Прогрессивные веб-приложения, офлайн-ориентированные приложения и медиаёмкие сайты выигрывают от знания своего бюджета хранилища. Однако значение квоты, возвращаемое navigator.storage.estimate(), выводится из реальных характеристик диска устройства. Chrome, например, обычно выделяет квоту на основе процента от общего доступного дискового пространства. Это означает, что возвращаемое значение косвенно раскрывает информацию о физическом оборудовании хранения пользователя, создавая сигнал фингерпринтинга, который сохраняется между сессиями и не подвержен обычным мерам приватности.

Влияние на приватность

Фингерпринтинг квоты хранилища вызывает озабоченность, поскольку конфигурация диска - это стабильная, аппаратно-специфичная характеристика. В отличие от cookies или данных сессии, доступное дисковое пространство на устройстве изменяется медленно (только при добавлении или удалении файлов или замене диска). Это означает, что значение квоты хранилища является постоянным идентификатором.

Последствия для приватности значительны:

  • Идентификация размера диска: устройство с SSD на 256 ГБ производит другое значение квоты, чем с 512 ГБ или 1 ТБ. Поскольку размеры дисков следуют стандартным производственным уровням (128, 256, 512, 1024 ГБ), значение квоты фактически раскрывает уровень хранилища.
  • Определение паттернов использования: соотношение между квотой и использованием раскрывает, насколько заполнен диск. Почти полный диск (высокое использование относительно квоты) ведёт себя иначе, чем свежеустановленная система. Со временем изменения этого соотношения могут раскрыть паттерны активности пользователя.
  • Идентификация операционной системы: разные операционные системы вычисляют квоты хранилища по-разному. Chrome на Windows, macOS и Linux применяют разные формулы и ограничения, что означает, что один и тот же физический диск производит разные значения квоты в зависимости от ОС.
  • Идентификация класса устройства: устройство с диском 2 ТБ, скорее всего, является десктопом или высококлассным ноутбуком, тогда как 64 ГБ предполагают бюджетный ноутбук или Chromebook. Эта информация о классе устройства дополняет другие аппаратные сигналы.

Исследование Университета Аделаиды продемонстрировало, что значения квоты хранилища в сочетании с другими сигналами, связанными с хранилищем (доступность IndexedDB, поведение Cache API, статус разрешения persistent storage), могут увеличить уникальность отпечатка на 5-10%. API не требует разрешений и не производит уведомлений.

Проблема усугубляется тем, что значение квоты не является статичным для устройства. Оно изменяется по мере использования и освобождения дискового пространства, создавая медленно эволюционирующий идентификатор, который можно отслеживать со временем. Пользователь, чья квота уменьшается на 20 ГБ за месяц, оставляет след состояния хранилища, который может быть сопоставлен с другими сигналами.

Техническая основа

Как работает navigator.storage.estimate()

Метод navigator.storage.estimate() возвращает промис, который разрешается в объект с двумя свойствами:

  • quota: общее пространство хранилища, доступное для источника, в байтах. Обычно это процент от общего дискового пространства с учётом ограничений и политик конкретного браузера.
  • usage: объём хранилища, используемого источником в данный момент, в байтах. Это включает данные в IndexedDB, Cache API, регистрации service worker и другие механизмы хранения.

Chrome вычисляет квоту как приблизительно 60% от общего доступного дискового пространства с дополнительными ограничениями для каждого источника. Firefox использует другую формулу на основе доступного свободного места. Safari устанавливает более строгие ограничения для каждого источника с механизмом увеличения через запрос.

Детали расчёта квоты

В Chrome (и браузерах на основе Chromium) расчёт квоты хранилища следует примерно такой логике:

  1. Определить общий размер тома дискового раздела, содержащего каталог профиля
  2. Рассчитать доступное свободное пространство на этом разделе
  3. Применить формулу на основе процентов (приблизительно 60% от общего для временного хранилища, с пулом, разделяемым между источниками)
  4. Применить ограничения для каждого источника, чтобы ни один источник не мог потребить всю квоту

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

Сигналы IndexedDB и Cache API

Помимо navigator.storage.estimate(), другие API хранилища могут раскрыть информацию о диске:

  • IndexedDB: максимальный размер базы данных определяется квотой хранилища. Попытки сохранить всё большие блобы могут раскрыть приблизительную квоту через границы успеха/неудачи.
  • Cache API: аналогично IndexedDB, Cache API разделяет ту же квоту хранилища, и попытки закешировать большие ответы раскрывают ограничения квоты.
  • Persistent storage: метод navigator.storage.persist() запрашивает постоянное хранилище (не подлежащее вытеснению). Успешность этого запроса и его влияние на квоту зависят от платформы.

Точность значений

Значение quota возвращается в байтах, обеспечивая очень высокую точность. Диск на 512 ГБ может дать квоту около 307 200 000 000 байт (приблизительно 60% от 512 ГБ), тогда как диск на 256 ГБ даёт примерно 153 600 000 000. Точное значение зависит от реального свободного пространства, других профилей и накладных расходов ОС, но порядок величины надёжно различает размеры дисков.

Эта точность означает, что даже небольшие различия в конфигурации диска, такие как разные схемы разделов или разные объёмы использованного пространства, производят различимые значения квоты.

Различия между браузерами

Разные браузеры вычисляют квоты по-разному:

  • Chrome: процент от общего дискового пространства с ограничениями для каждого источника
  • Firefox: на основе доступного свободного места, с расчётами разных уровней
  • Safari: фиксированные ограничения для каждого источника (обычно 1 ГБ изначально, расширяемые с разрешения пользователя)
  • Edge: аналогично Chrome (на основе Chromium)

Эти различия означают, что одно и то же физическое устройство производит разные значения квоты в разных браузерах, добавляя ещё одно измерение к отпечатку.

Распространённые подходы защиты и их ограничения

VPN и прокси-серверы

VPN не влияют на значения квоты хранилища. Квота определяется полностью локальной конфигурацией диска и расчётами браузера. Средства приватности сетевого уровня не могут изменить характеристики локального хранилища.

Инкогнито и приватный просмотр

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

Расширения браузера

Расширения могут перехватывать промис navigator.storage.estimate() и возвращать модифицированные значения:

  • Фиксированные значения: возврат жёстко заданной квоты (например, всегда 100 ГБ) обнаруживаем, если значение не меняется между сессиями или не коррелирует с другими сигналами, связанными с диском.
  • Округление: округление квоты до общего значения уменьшает точность, но может не соответствовать ожидаемому значению для эмулируемой комбинации браузера и ОС.
  • Перехват промисов: переопределение navigator.storage.estimate или его прототипа обнаруживаемо через проверки дескрипторов свойств и цепочки прототипов.

Уменьшение использования диска

Использование меньшего раздела или диска изменяет квоту, но пользователи не могут легко контролировать размер своего диска для целей приватности. Это аппаратная характеристика, которую фундаментально трудно модифицировать.

Подход BotBrowser на уровне движка

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

Значения квоты на основе профиля

chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="$(mktemp -d)"

Профиль включает значения квоты хранилища, собранные с реальных устройств. Эти значения реалистичны для класса целевого устройства профиля: профиль ноутбука с SSD на 512 ГБ сообщает значения квоты, согласованные с этой конфигурацией, независимо от реального размера диска хостовой машины.

Внутренне согласованные сигналы хранилища

BotBrowser обеспечивает согласованность результатов всех API, связанных с хранилищем:

  • navigator.storage.estimate() возвращает определённые профилем значения квоты и использования
  • Поведение хранилища IndexedDB соответствует заявленной квоте
  • Поведение Cache API согласовано с бюджетом хранилища
  • Соотношение квоты/использования реалистично для целевого класса устройства
  • Значения стабильны на протяжении всей сессии

Кросс-платформенная точность

Поскольку разные браузеры вычисляют квоты по-разному, профили BotBrowser включают значения квот, специфичные для браузера. Профиль Chrome возвращает расчёты квоты, характерные для Chrome, при этом различия в формулах между браузерами учтены в данных профиля.

Предотвращение утечек диска хоста

Основная цель - предотвратить утечку конфигурации диска хостовой машины через API хранилища. Независимо от того, работает ли BotBrowser на сервере 128 ГБ или рабочей станции 4 ТБ, значения квоты хранилища, сообщаемые веб-страницам, отражают целевое устройство профиля, а не реальное оборудование хоста.

Контроль значения использования

Значение usage (текущее потребление хранилища) также контролируется. Свежезагруженный профиль сообщает минимальное использование, и значение естественно эволюционирует по мере сохранения данных источником во время сессии, но всегда в контексте системы квот профиля.

Конфигурация и использование

Базовое использование CLI

Защита квоты хранилища активируется автоматически при загрузке профиля:

chrome --bot-profile="/path/to/profile.enc" \
       --user-data-dir="$(mktemp -d)"

Дополнительные флаги не требуются.

Интеграция с Playwright

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
    ],
    headless: true,
  });

  const context = await browser.newContext({ viewport: null });
  const page = await context.newPage();

  const storageInfo = await page.evaluate(async () => {
    const estimate = await navigator.storage.estimate();
    return {
      quota: estimate.quota,
      usage: estimate.usage,
      quotaGB: (estimate.quota / (1024 ** 3)).toFixed(2),
      usageMB: (estimate.usage / (1024 ** 2)).toFixed(2),
    };
  });

  console.log('Storage info:', storageInfo);
  await browser.close();
})();

Интеграция с Puppeteer

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/path/to/profile.enc',
    ],
    headless: true,
    defaultViewport: null,
  });

  const page = await browser.newPage();
  await page.goto('about:blank');

  const quota = await page.evaluate(async () => {
    const est = await navigator.storage.estimate();
    return { quota: est.quota, usage: est.usage };
  });

  console.log('Quota:', quota.quota, 'bytes');
  console.log('Usage:', quota.usage, 'bytes');
  await browser.close();
})();

Комбинирование с другими защитами

Для комплексного контроля идентичности устройства:

chrome --bot-profile="/path/to/profile.enc" \
       --bot-noise-seed=42 \
       --proxy-server="socks5://user:pass@proxy:1080" \
       --bot-config-timezone="America/Chicago" \
       --user-data-dir="$(mktemp -d)"

Верификация

После запуска BotBrowser с профилем проверьте значения квоты хранилища:

const estimate = await navigator.storage.estimate();
const quotaGB = (estimate.quota / (1024 ** 3)).toFixed(2);
const usageMB = (estimate.usage / (1024 ** 2)).toFixed(2);

console.log(`Quota: ${quotaGB} GB (${estimate.quota} bytes)`);
console.log(`Usage: ${usageMB} MB (${estimate.usage} bytes)`);

// Убедитесь, что квота отражает профиль, а не хост
// Профиль для устройства 256 ГБ должен показывать примерно 60% от 256 ГБ
// Профиль для устройства 1 ТБ должен показывать пропорционально большее значение

Что проверять:

  1. Значение квоты реалистично для класса целевого устройства профиля (не хостовой машины)
  2. Квота не совпадает с реальным размером диска вашего хоста
  3. Значение использования разумно (низкое для свежей сессии, увеличивающееся при сохранении данных)
  4. Значения стабильны при перезагрузках страницы в рамках одной сессии
  5. Разные профили производят разные значения квоты
  6. Инструменты тестирования отпечатков не показывают аномалий, связанных с хранилищем

Лучшие практики

  1. Используйте полные профили. Значения квоты хранилища должны быть согласованы с остальной идентичностью устройства. Профиль, заявляющий себя мобильным устройством, не должен сообщать квоту 2 ТБ.

  2. Согласовывайте user-data-dir со сценарием использования. Свежий user-data-dir (через mktemp -d) начинает с минимальным использованием. Для постоянных сессий повторно используйте тот же каталог данных, чтобы значения использования эволюционировали естественно.

  3. Учитывайте обнаружение инкогнито. Если ваш рабочий процесс требует предотвращения обнаружения инкогнито, учтите, что поведение квоты хранилища различается между обычным режимом и инкогнито. Профили BotBrowser в обычном режиме сообщают стандартные значения квоты.

  4. Проверяйте относительно реального хоста. Запустите navigator.storage.estimate() на вашей хостовой машине вне BotBrowser, чтобы узнать реальное значение квоты, затем убедитесь, что профиль BotBrowser сообщает другое значение.

Часто задаваемые вопросы

Раскрывает ли квота хранилища точный размер диска?

Не совсем. Квота - это процент от доступного дискового пространства (примерно 60% в Chrome), и она изменяется по мере использования дискового пространства. Однако значение квоты надёжно различает уровни размера диска (128 ГБ vs. 256 ГБ vs. 512 ГБ vs. 1 ТБ), что делает его полезным сигналом фингерпринтинга.

Могут ли веб-сайты определить ограничения хранилища без navigator.storage.estimate()?

Да. Пытаясь записать всё большие блобы в IndexedDB или Cache API, веб-сайт может обнаружить ограничение хранилища методом проб и ошибок. BotBrowser контролирует базовую систему квот, поэтому и API estimate, и фактическое поведение хранилища отражают конфигурацию профиля.

Изменяется ли квота хранилища в режиме инкогнито?

Да. Режим инкогнито обычно использует временную файловую систему с другой квотой. Значение квоты в инкогнито часто значительно ниже, чем в обычном режиме, что может быть использовано для обнаружения инкогнито. Профили BotBrowser в обычном режиме сообщают стандартные значения квоты.

Насколько точна квота как отпечаток?

Значение quota возвращается в байтах, обеспечивая очень высокую точность. Однако, поскольку значение колеблется при изменении дискового пространства, оно наиболее полезно как грубый идентификатор (уровень размера диска), а не как точный. В сочетании с другими сигналами оно вносит значимый вклад в общий отпечаток.

Контролирует ли BotBrowser Persistent Storage API?

Метод navigator.storage.persist() и связанное с ним поведение контролируются профилем. Профиль определяет, доступно ли постоянное хранилище и как расчёты квоты зависят от статуса постоянного хранения.

Как насчёт устаревшего API webkitStorageInfo?

Более старые версии Chromium предоставляли квоту хранилища через webkitStorageInfo и navigator.webkitTemporaryStorage. Профили BotBrowser контролируют и эти устаревшие API, обеспечивая согласованные значения для старых скриптов фингерпринтинга.

Может ли квота хранилища раскрыть, что я работаю в контейнере?

Контейнеры и виртуальные машины часто имеют меньшие выделения диска, чем физические машины. Docker-контейнер с томом 20 ГБ производит совсем другую квоту, чем физическая машина с SSD на 1 ТБ. Подход BotBrowser на основе профилей обеспечивает, что сообщаемая квота соответствует целевому устройству, а не реальному хранилищу контейнера.

Итоги

navigator.storage.estimate() из Storage Manager API раскрывает характеристики диска, которые служат постоянным сигналом фингерпринтинга. Значение квоты косвенно раскрывает размер диска, класс устройства и операционную систему через специфичные для браузера формулы расчёта. BotBrowser контролирует все ответы квоты хранилища на уровне движка через свою систему профилей, обеспечивая, что сообщаемые значения соответствуют целевому устройству и не раскрывают информацию о реальной конфигурации диска хостовой машины. По связанным темам смотрите защита свойств Navigator, контроль тайминга производительности и комплексное управление профилями.

#Storage#Quota#fingerprinting#Privacy#Indexeddb#Disk

Переведите BotBrowser из исследований в продакшн

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