ブラウザフィンガープリント防御ガイド:Canvasフィンガープリントからプライバシーファーストの追跡防止戦略まで

前端工程(更新: 2026年6月2日)

ブラウザフィンガープリント:Cookie不要の追跡技術

Cookieを無効にし、シークレットモードを使用しても、Webサイトはブラウザフィンガープリントを通じてあなたを一意に識別できます—精度は最大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. ブラウザプライバシー設定:Firefoxのprivacy.resistFingerprinting

5. 総合フィンガープリントエントロピー分析

情報次元 エントロピー(bits) 累積一意性
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):オープンソースフィンガープリントライブラリデモ

フィンガープリント削減のヒント

  1. Firefox + privacy.resistFingerprinting = trueを使用
  2. Torブラウザを使用(統一フィンガープリント)
  3. プライバシー拡張機能を使用(Privacy Badger、uBlock Origin)
  4. 希少なフォントのインストールを避ける
  5. 標準解像度とスケーリング比率を使用

ブラウザローカルツールを無料で試す →

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