Руководство по защите от цифрового отпечатка браузера: от Canvas Fingerprinting до стратегий антиотслеживания с приоритетом конфиденциальности
Цифровой отпечаток браузера: отслеживание без файлов cookie
Даже при отключённых файлах 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;
}
Методы защиты
Перечисление шрифтов сложнее всего защитить, поскольку оно использует обычные возможности рендеринга текста браузера. Ключевые стратегии:
- Ограничить загрузку шрифтов: Разрешить только системные шрифты
- CSS font-display: block: Задерживать несущественные шрифты
- Настройки конфиденциальности браузера:
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 с открытым исходным кодом
Советы по уменьшению вашего отпечатка:
- Используйте Firefox +
privacy.resistFingerprinting = true - Используйте Tor Browser (единообразный отпечаток)
- Используйте расширения для конфиденциальности (Privacy Badger, uBlock Origin)
- Избегайте установки редких шрифтов
- Используйте стандартные разрешения и масштабирование
Попробуйте эти локальные браузерные инструменты — регистрация не требуется →