0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Webサービスを作る側として、ブラウザフィンガープリンティングの仕組みをザックリ整理してみた

0
Posted at

はじめに

Cookieを消してもシークレットウィンドウを使っても、なぜか「あなた、この前も来ましたよね」と見抜いてくるサイトがある。あの気持ち悪さの正体が、ブラウザフィンガープリンティングです。

先に結論だけ言うと、こういう話です。

  • フィンガープリンティングは、ブラウザや端末の「微妙なクセ」をかき集めて1つのIDにする技術
  • Cookieと違って端末に何も保存しないので、消しても再現されやすい
  • 不正検知のような正当な用途がある一方、勝手なトラッキングは各国の法律で規制対象になっている
  • 作る側は「何のために使うか」で天国と地獄が分かれる

対象読者はこんな人です。

  • Webサービスを作っていて、フィンガープリンティングという言葉は知っているが仕組みは曖昧な人
  • 不正検知やbot対策に興味があるが、規制的にどこまでOKか不安な人
  • 「Cookie廃止どうなったの?」の最新状況をざっくり知りたい人

なぜ私がこれを書くのか。自分でWebサービスを触っていて、「不正ログインを弾きたいな、fingerprintのライブラリを入れれば端末を見分けられて楽じゃん」と軽い気持ちで調べ始めたら、思ったより仕組みが面白く、かつ「これ、使い方を一歩間違えると規制に触れるやつだ」と気づいて手が止まった——というのが動機です。同じ立場の人に向けて、仕組みと線引きを一度整理しておきます。深追いはせず、まず全体像をつかむのを目的にします。

参考文献

細かい話に入る前に、一次情報を置いておきます。まず自分で当たりたい人はこちらへ。

MDNは技術仕様側の視点、EFFのCover Your Tracksは「自分のブラウザがどれだけ特定されやすいか」を実際に測れるツール、W3Cのガイダンスは標準化団体がフィンガープリンティングをどう問題視しているかの一次資料です。

そもそもフィンガープリンティングとは(Cookieとの決定的な違い)

一言でいうと、ブラウザや端末に現れる細かな差異を寄せ集めて、その組み合わせで個人(正確には「その端末+ブラウザ」)を識別する技術です。指紋(fingerprint)という名前のとおり、一人ひとり微妙に違うクセを読み取っています。

Cookieとの一番の違いは、端末に「印」を残さないことです。

Cookieは「あなたはID: xxx ですよ」という付箋を端末に貼りつける方式なので、ユーザーが付箋を剥がせば(削除すれば)足跡は消えます。一方フィンガープリンティングは、端末側には何も書き込みません。訪問のたびに「画面サイズは? フォントは? GPUは?」と特徴を集め、その場でIDを計算し直します。

だから厄介なんです。Cookieを消しても、シークレットモードにしても、特徴そのものは大きくは変わらないので、また同じIDが再現されやすい。ここが「消したはずなのに追跡される」のカラクリです。ただし「必ず同じIDになる」わけではなく、共有PCや複数プロファイル、後述する耐フィンガープリント処理があると再現しないこともあります。あくまで識別するのは「そのブラウザ環境」であって、物理的な端末や個人と一対一で結びつくとは限りません。

もっとも、万能でもありません。ブラウザを更新したり拡張機能を入れたりすると特徴が変わってIDがずれることもある。あくまで「そこそこ安定した推定」だと思ってください。

なぜ「ちょっとした違い」で個人が特定できるのか(エントロピーの話)

ここが仕組みの核なので、少しだけ丁寧に書きます。

画面解像度だけを見ても、世の中には同じ解像度の人が山ほどいるので特定はできません。でも「解像度 × 言語 × タイムゾーン × フォント構成 × GPU × ……」と条件を重ねていくと、一致する人がどんどん減っていく。最終的に「その組み合わせ、世界であなただけですね」というところまで絞れてしまう。この絞り込みの度合いを情報量(エントロピー)で測ります。

fingerprint-entropy.png

ざっくり言うと、シグナルが1つ増えるごとに候補が半分ずつ減っていくイメージです。1回半分になれば1ビット。これが積み上がると効きます。あくまで「各シグナルが均等かつ独立にバラけている」と仮定したときの目安ですが、感覚をつかむにはこれで十分です。

  • 10ビット → 約1,000人に1人
  • 20ビット → 約100万人に1人
  • 33ビット → 約86億通り(地球の人口を超える)

ここで大事なのは、ビット数はあくまで「何通りに分けられるか」の目安であって、一人ずつ確実に別のIDになる(=一意性)を保証するものではない、という点です。同じ組み合わせの人がたまたま複数いれば、そこは区別できません。

具体的な数値には幅があります。フィンガープリンティング研究の古典であるEFFの調査では、識別に使える情報量は平均でおおよそ18ビット程度と報告されました。測る属性を増やせば数十ビットに達するという報告もありますが、いずれも「測定した属性・母集団・時点」に強く依存する数字です。「平均◯◯ビット」という単一の絶対値があるわけではない、と受け取ってください。

そして、これらは相関で目減りします(このGPUを積んだ端末はこの解像度が多い、など)。時間でも変わる。それでも「Cookieなしでかなり絞れる」水準ではある、というのが正直なところです。

代表的なシグナルの仕組み

では、具体的にどんな特徴を集めているのか。代表的なものを見ていきます。全部を網羅すると長くなるので、面白くて仕組みが分かりやすいものに絞ります。

Canvasフィンガープリント

一番有名で、一番「よくできてるな」と感心したのがこれです。

やっていることは単純で、画面には見えない小さなCanvasに文字や図形を描かせ、その結果のピクセルを読み取るだけ。ポイントは、同じ描画命令でも出力ピクセルが端末ごとに微妙にズレるという事実です。GPU・グラフィックドライバ・インストールされているフォント・OSのアンチエイリアス処理などが少しずつ違うため、文字の縁のにじみ方が端末ごとに変わる。その微妙な差をハッシュ化すれば識別子になります。

イメージを掴むための最小コードはこんな感じです。

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

ctx.textBaseline = 'top';
ctx.font = "16px 'Arial'";
ctx.fillStyle = '#f60';
ctx.fillRect(10, 10, 100, 30);
ctx.fillStyle = '#069';
ctx.fillText('Hello, fingerprint 😃', 12, 15);

// 同じ命令でも、GPU・ドライバ・フォント・OSの違いで
// 出力ピクセルが微妙にズレる。この文字列をハッシュにかけて指紋にする。
const raw = canvas.toDataURL();

絵文字をわざと混ぜているのも定番のテクニックで、絵文字のレンダリングはOSやフォントによる差が特に大きく、識別の効きが良いからです。人間の目には同じ文字でも、機械にとっては指紋というわけです。

WebGL / GPU フィンガープリント

Canvasが2D描画の微差を見るのに対して、WebGLはGPUそのものの3D描画能力に踏み込みます。3Dのシーンをレンダリングさせて、その出力ピクセルの差を見る。加えて、GPUのベンダー名やモデル名を読み取れる場合もあり、これも強いシグナルになります。要は「あなたのグラフィックボード、これですよね」を当てにいくわけです。

Audioフィンガープリント

これを知ったときは正直「そこまでやるのか」と声が出ました。音声処理の微差を使う手法です。

Web Audio APIで、鳴らさずに(オフラインで)音の波形を生成させ、その出力バッファを読み取る。スピーカーには一切出さないので、これで見えるのは「音響ハードウェアの差」ではなく、ブラウザのオーディオ処理(DSP)の実装・丸め・リサンプリングや、CPUアーキテクチャの違いによる数値の微差です。同じ波形を計算させても、その数値がわずかにズレるので、それを指紋にします。音を再生する必要すらないので、ユーザーは何も気づきません。

その他のシグナル(フォント・画面・言語・TLSなど)

派手ではないけれど、組み合わせに効いてくる地味なシグナルもたくさんあります。

  • インストール済みフォントの推測(普通は一覧を直接は取れず、文字の描画幅などから「入っているっぽい」を推定する。会社支給PCと個人PCで結構違う)
  • 画面の解像度・色深度・デバイスピクセル比
  • 言語設定・タイムゾーン
  • User-Agent、対応している機能、拡張機能の痕跡(拡張が注入する要素などの副作用から間接的に推測される)
  • TLSハンドシェイクのクセ(サーバ側から観測できる)

一個ずつは弱くても、前述のとおり掛け算で効いてきます。「弱いシグナルを大量に束ねる」のがこの技術のいやらしさであり、うまさでもあります。

集めたシグナルを1つのIDにするまで

ここまでの流れを1枚にまとめると、こうなります。

fingerprint-dataflow.png

やっていることは3ステップです。

  1. ブラウザ・端末からシグナルを集める(Canvas / WebGL / Audio / フォント……)
  2. それらを正規化して1本の文字列に連結し、ハッシュ化する(SHA-256など)
  3. サーバ側で保存済みのIDと照合し、「同じ訪問者だ」と推定する

図にすると「一直線じゃん」と拍子抜けするかもしれません。でも本当にこれだけで、Cookieなしに訪問者をまたいで追える。シンプルだからこそ強力なんです。

ただし2つ補足を。まず、ハッシュ化はIDを短く扱いやすくするだけで、匿名化ではありません。入力の識別力(=どれだけ個人を絞れるか)はハッシュにかけても1ミリも減らない。「ハッシュだから個人情報じゃない」は誤解です。次に、SHA-256のようなハッシュは入力が1ビットでも変われば出力が総取っ替えになるので、ブラウザ更新などで特徴が少し変わると「完全一致」では一気に別人扱いになります。だから実運用の識別は、単純な完全一致だけに頼らず、属性ごとの一致度や過去の履歴を使った確率的な照合になっているのが普通です。図の3ステップは、あくまで骨格の理解用と思ってください。

精度は実際どれくらい出るのか

「で、結局どのくらい当たるの?」が気になりますよね。ここは提供形態でかなり差が出ます。

商用のフィンガープリント系サービスは、サーバ側の追加情報や機械学習まで組み合わせて、IPやCookieを変えても9割以上の精度で同一端末を言い当てる、とうたっているものがあります。一方、ブラウザだけで完結するオープンソースのライブラリ単体だと、精度はぐっと下がる(数割程度)とされます。この差は、クライアント側のシグナルだけでなく、サーバ側で観測できる情報や過去の履歴をどれだけ足せるかの差だと理解しておくと、営業資料の「99%」に振り回されずに済みます。

ここで注意したいのは、この「精度」という言葉が曲者だということ。同一端末をどれだけ再識別できたか(取りこぼしの少なさ)と、別人を同一人と誤って結びつけてしまう率(誤一致)は別の指標で、ベンダーの公表値がどちらを指しているかは資料によってバラバラです。だから他社やOSSの数字と単純比較しても意味は薄い。結局、自分のトラフィックで、どの指標をどう測ったかまで込みで見るしかありません。

ここで出した精度は各社・各ライブラリの公表値やベンチマークに基づく概数で、条件によって大きく変わります。導入を検討するなら、自分のトラフィックで実測するのが結局いちばん確実です。

なぜ今あらためて話題なのか(サードパーティCookie廃止の撤回)

フィンガープリンティングがここ最近また注目されているのには、はっきりした理由があります。「Cookieの代わり」として脚光を浴びたからです。

長らく「Chromeがサードパーティ Cookieを廃止する」という話が続いていました。ところが流れが変わります。2024年7月にGoogleは「全廃はしない」と方針転換し、さらに2025年4月には「ユーザーに選択を迫るプロンプトも出さない」と発表しました。つまり、サードパーティ Cookieはとりあえず生き残った、というのが執筆時点(2026年8月)の状況です。

とはいえSafariのトラッキング防止やブラウザ側の対策で、Cookieに頼った追跡がやりにくくなっているのは事実です。その隙間を埋める「Cookieに依存しない識別手段」として、フィンガープリンティングへの関心がまた高まっている——という構図です。皮肉なもので、プライバシー強化の圧力が、より見えにくい追跡技術を後押しした面があります。

作る側の線引き:不正検知は正当化されやすい、でも無条件ではない

さて、ここが私がいちばん知りたかったところです。作る側として、どこまでやっていいのか。

大事なのは、フィンガープリンティングは技術としては中立で、用途によって評価が正反対になるということ。同じ技術が、こう分かれます。

  • 正当とされやすい用途: 不正ログイン・bot・クレジットカードの不正利用の検知、多重アカウントの抑止といったセキュリティ目的
  • 問題になりやすい用途: 本人の同意なく、広告やプロファイリングのために横断追跡すること

法律の面でも、この区別はおおむね共通しています。

  • EUでは、まず端末の情報にアクセスすること自体がePrivacy指令(5条3項)の対象で、原則として同意が必要です(サービス提供に真に必要な場合などの例外はある)。フィンガープリントもこの「端末情報へのアクセス」に当たるという解釈が定着しています。加えて、集めた情報が個人データに当たれば、GDPR側で適法根拠・透明性・目的制限なども別途満たす必要があります。「同意さえ取ればOK」でも「同意だけが根拠」でもなく、2階建てで見るのがポイントです
  • 日本でも、2023年6月施行の改正電気通信事業法(外部送信規律)が関係します。これはCookieに限らず端末の情報を外部送信する場合に、利用者への確認機会(通知・公表・同意取得・オプトアウトのいずれか)を求める制度です。ただし全サイト・全情報に一律ではなく、対象となる役務や情報、除外される必要な情報などの線引きがあるので、自社が該当するかは個別確認が要ります

「セキュリティ目的なら完全に無罪」というわけではありません。目的が正当でも、必要な範囲か・より弱い手段はないか(データ最小化)といった観点は問われます。不正検知のつもりで集めた識別子を、あとからマーケティング分析に流用する——といった目的外利用は、同意の前提が崩れてアウトになりがちです。「何のために集め、何に使うか」をはっきり決めて、そこからはみ出さないことが実務上のキモです。実装の前に、自社のプライバシーポリシーと外部送信の告知を必ず点検してください。

技術的な注意も1つ。フィンガープリントは変わるし、偽装もできます。だから「このフィンガープリントだから即ログイン拒否/即許可」のように単独の判定材料にするのは危険です。あくまでリスクスコアの一要素として、追加認証やレート制限など他の仕組みと組み合わせて使うのが安全側です。

私が最初に「fingerprintライブラリを入れれば楽に端末を見分けられる」と考えたのは、技術としては正しくても、運用としては半分しか見ていなかった。「集められる」と「集めていい」は別問題で、後者を詰めずに入れるのは危ない。ここに気づけたのが、今回いちばんの収穫でした。

対策する側(ブラウザ・ユーザー)は何をしているか

追跡される側の防御も進んでいます。仕組みを知ると、対策の狙いも読めるようになります。

  • 一部のブラウザは、Canvasやフォントの読み取りに対して、わざと微妙なノイズを混ぜたり、多くのユーザーで同じ値に見せかけたりして、指紋を「みんな同じ」にしてしまう
  • Torブラウザは、そもそも全員のフィンガープリントを揃える方向で設計されていて、「あなただけの特徴」を作らせない
  • 拡張機能や設定で、User-Agentや各種APIの値を統一・制限する

面白いのは、対策のアプローチが2種類に分かれることです。「ノイズを足して毎回変える」方向と、「みんな同じ値に揃えて埋もれさせる」方向。後者のほうが筋が良いとされます。値がコロコロ変わると、逆に「変わること自体」が特徴になってしまうからです。防御でうっかり目立つ、というのは示唆に富んでいます。

まとめ(作る側としての所感)

ざっくり理解を目的に整理してきましたが、私の結論はこうです。

フィンガープリンティングは、弱いシグナルを大量に束ねて掛け算で一意に持っていく、シンプルだけど強力な技術でした。Cookieのように消せないぶん、便利さと気持ち悪さが表裏一体になっている。だからこそ、作る側の姿勢が全てを決めます。「技術的にできるか」ではなく「何のために、どこまで使うか」を先に決める。それさえ握れていれば、不正検知のような用途で正当化しやすい武器になるし、握れていないと、気づかないうちに規制の地雷を踏む。

あなたのサービスでは、識別のためにどのシグナルを、何の目的で集めていますか。もし答えに詰まるなら、実装より先にそこを言語化するのがおすすめです。

次は、実際に不正検知の文脈でフィンガープリントをどう「同意の設計」と両立させるか——CMPや外部送信の告知まわりの実装を、手を動かしながら書いてみたいと思っています。試した人がいたら、どのライブラリでどこまでやったか、ぜひ教えてください。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?