Руководство по защите от цифрового отпечатка браузера: от Canvas Fingerprinting до стратегий антиотслеживания с приоритетом конфиденциальности

前端工程

Даже при отключённых файлах cookie и включённом режиме инкогнито веб-сайты могут однозначно идентифицировать вас через цифровой отпечаток браузера — с точностью до 99,1%.

Тип отпечатка Стабильность Уникальность Сложность защиты
User-Agent Низкая (меняется с обновлениями) Средняя Низкая
Canvas Высокая Высокая Средняя
WebGL Высокая Высокая Средняя
AudioContext Высокая Средняя Средняя
Перечисление шрифтов Высокая Высокая Высокая
Разрешение экрана Высокая Средняя Низкая
Часовой пояс/Язык Высокая Низкая Низкая

1. Отпечаток Canvas

Принцип работы

Различные GPU, драйверы и алгоритмы сглаживания на разных устройствах создают тонкие различия в одном и том же выводе рендеринга Canvas:

function getCanvasFingerprint() {
  const canvas = document.createElement('canvas');
  canvas.width = 200;
  canvas.height = 50;
  const ctx = canvas.getContext('2d');

  // Рендеринг текста и фигур
  ctx.textBaseline = 'top';
  ctx.font = '14px Arial';
  ctx.fillStyle = '#f60';
  ctx.fillRect(125, 1, 62, 20);
  ctx.fillStyle = '#069';
  ctx.fillText('Hello, world! 🌍', 2, 15);
  ctx.fillStyle = 'rgba(102, 204, 0, 0.7)';
  ctx.fillText('Hello, world! 🌍', 4, 17);

  // Извлечение данных пикселей и хеширование
  const data = canvas.toDataURL();
  return hash(data); // напр., "a1b2c3d4..."
}

Методы защиты

Метод 1: Внедрение шума

// Переопределить toDataURL для добавления тонкого случайного шума
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;

HTMLCanvasElement.prototype.toDataURL = function (...args) {
  const ctx = this.getContext('2d');
  if (ctx) {
    // Добавить случайные пиксели в незаметных позициях
    const imageData = ctx.getImageData(0, 0, this.width, this.height);
    const noise = Math.random() * 0.01;
    imageData.data[0] = Math.min(255, imageData.data[0] + noise);
    ctx.putImageData(imageData, 0, 0);
  }
  return originalToDataURL.apply(this, args);
};

Метод 2: Возврат фиксированных значений

// Все canvas возвращают одно и то же пустое изображение
HTMLCanvasElement.prototype.toDataURL = function () {
  return 'data:image/png;base64,...'; // Фиксированное пустое изображение
};

2. Отпечаток WebGL

Принцип работы

WebGL раскрывает информацию о рендерере и производителе GPU, а разные GPU дают разные результаты рендеринга:

function getWebGLFingerprint() {
  const canvas = document.createElement('canvas');
  const gl = canvas.getContext('webgl');

  const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
  const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
  const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);

  // Рендеринг тестовой сцены
  // ... Разные GPU дают разные результаты пикселей

  return { vendor, renderer, renderHash };
}

Часто утекаемая информация

Информация Пример
Производитель GPU "NVIDIA Corporation", "Intel", "AMD"
Рендерер GPU "GeForce RTX 4090", "Apple M2"
Максимальный размер текстуры 16384, 8192
Максимальные атрибуты вершин 16
Список поддерживаемых расширений 30+ названий расширений

Метод защиты

// Скрыть информацию о GPU
const getParameter = WebGLRenderingContext.prototype.getParameter;

WebGLRenderingContext.prototype.getParameter = function (param) {
  if (param === 37445) return 'Intel Inc.';    // UNMASKED_VENDOR
  if (param === 37446) return 'Intel Iris';    // UNMASKED_RENDERER
  return getParameter.call(this, param);
};

3. Отпечаток AudioContext

Принцип работы

Аудиопроцессоры (DSP) разных устройств создают тонкие различия при обработке одного и того же сигнала:

function getAudioFingerprint() {
  const context = new OfflineAudioContext(1, 44100, 44100);

  const oscillator = context.createOscillator();
  oscillator.type = 'triangle';
  oscillator.frequency.setValueAtTime(10000, context.currentTime);

  const compressor = context.createDynamicsCompressor();
  compressor.threshold.setValueAtTime(-50, context.currentTime);
  compressor.knee.setValueAtTime(40, context.currentTime);
  compressor.ratio.setValueAtTime(12, context.currentTime);

  oscillator.connect(compressor);
  compressor.connect(context.destination);
  oscillator.start(0);

  return context.startRendering().then(buffer => {
    const data = buffer.getChannelData(0);
    return hash(data.slice(4500, 5000));
  });
}

Метод защиты

// Добавить шум к выводу AudioContext
const originalStartRendering = OfflineAudioContext.prototype.startRendering;

OfflineAudioContext.prototype.startRendering = function () {
  return originalStartRendering.call(this).then(buffer => {
    const data = buffer.getChannelData(0);
    for (let i = 0; i < data.length; i++) {
      data[i] += (Math.random() - 0.5) * 1e-7;
    }
    return buffer;
  });
};

4. Отпечаток через перечисление шрифтов

Принцип работы

Измеряя ширину рендеринга различных названий шрифтов, можно определить, какие шрифты установлены в системе пользователя:

function detectFonts() {
  const testFonts = [
    'Arial', 'Helvetica', 'Times New Roman',
    'Courier', 'Verdana', 'Georgia',
    'Comic Sans MS', 'Impact', 'Tahoma',
    'Microsoft YaHei', 'PingFang SC',
  ];

  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');

  const baseFonts = ['monospace', 'serif', 'sans-serif'];
  const results = {};

  for (const font of testFonts) {
    for (const base of baseFonts) {
      ctx.font = `72px ${base}`;
      const baseWidth = ctx.measureText('mmmmmmmmll').width;
      ctx.font = `72px "${font}", ${base}`;
      const testWidth = ctx.measureText('mmmmmmmmll').width;
      if (baseWidth !== testWidth) {
        results[font] = true;
        break;
      }
    }
  }

  return results;
}

Методы защиты

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

  1. Ограничить загрузку шрифтов: Разрешить только системные шрифты
  2. CSS font-display: block: Задерживать несущественные шрифты
  3. Настройки конфиденциальности браузера: privacy.resistFingerprinting в Firefox

5. Комплексный анализ энтропии отпечатка

Информационное измерение Энтропия (бит) Кумулятивная уникальность
User-Agent ~10 2^10 = 1 024
Разрешение экрана ~5 2^15
Часовой пояс ~5 2^20
Установленные шрифты ~15 2^35
Canvas ~15 2^50
WebGL ~10 2^60
AudioContext ~5 2^65

2^65 ≈ 3,7 × 10^19, достаточно для однозначной идентификации каждого устройства на Земле.


6. Архитектура приложений с приоритетом конфиденциальности

Стратегия конфиденциальности ToolsKu

Файлы пользователя → Локальная обработка в браузере → Прямая загрузка результата
         ↑
    Без транзита через сервер
    Без хранения данных
    Без отслеживающих cookie
    Без сбора цифрового отпечатка браузера

Контрольный список реализации

Стратегия Реализация Приоритет
Без стороннего отслеживания Удалить скрипты вроде Google Analytics P0
CSP ограничивает внешние ресурсы default-src 'self' P0
Без установки cookie Статическому сайту не нужны cookie P0
Referrer-Policy strict-origin-when-cross-origin P1
Permissions-Policy Ограничить доступ к API P1
Заявление о конфиденциальности Чётко раскрыть обработку данных P1
Архитектура локальной обработки Все вычисления выполняются в браузере P0

Конфигурация заголовков безопасности HTTP

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

7. Проверьте свой собственный отпечаток

Мы рекомендуем использовать следующие инструменты для проверки уникальности вашего цифрового отпечатка браузера:

  • AmIUnique (amiunique.org): Комплексное обнаружение отпечатка
  • BrowserLeaks (browserleaks.com): Детальный анализ Canvas/WebGL/Audio
  • FingerprintJS (fingerprintjs.com): Демо библиотеки fingerprinting с открытым исходным кодом

Советы по уменьшению вашего отпечатка:

  1. Используйте Firefox + privacy.resistFingerprinting = true
  2. Используйте Tor Browser (единообразный отпечаток)
  3. Используйте расширения для конфиденциальности (Privacy Badger, uBlock Origin)
  4. Избегайте установки редких шрифтов
  5. Используйте стандартные разрешения и масштабирование

Попробуйте эти локальные браузерные инструменты — регистрация не требуется →

#浏览器指纹#隐私安全#Canvas#WebGL#反追踪