ゲームプログラマの Nolen Royalty 氏が「すべての UUID v4 をリスト管理してウェブで閲覧できる」アプリ Every UUID V4 を公開し、自身のブログで技術的課題を語っている。UUID v4 は 122 bit のランダム識別子で、空間サイズは約 5.3 × 10^36 通り。地球上のすべての原子に1つずつ割り当ててもまだ余るオーダーで、そもそも全列挙は物理的に不可能だ。氏の本当の関心は、無限に近いリストを「あたかも事前保存されているように」スクロールさせる UI 実装と、ジャンプ検索のレスポンス設計にあった。
なぜハッカー視点で面白いのか #
UUID は開発現場で「衝突しない・推測されない一意 ID」として濫用される。だが 「衝突しない」と「推測されない」は別の話だ。Every UUID V4 は前者を視覚的に裏付けただけで、後者を保証してはいない。実装によって UUID は驚くほど予測可能になる。
| バージョン | 構造 | セキュリティ上の論点 |
|---|---|---|
v1 | タイムスタンプ + MAC アドレス | MAC が露出するため、発行端末を特定できる |
v4 | 122 bit の乱数 | CSPRNG なら安全。Math.random() 由来だと予測可能 |
v7 | ms 単位 UNIX 時刻 + 乱数 | 順序保持のため、生成タイミングが漏れる |
実際、Node.js の弱い乱数器で生成された v4 が攻撃者に予測されたケースや、Java の Math.random() で作ったセッショントークン UUID が現実的な時間でブルートフォースされた事例が報告されてきた。UUID というフォーマットの見た目に騙されてはいけない。
認証トークンに UUID を使ってはならない #
セッション ID、パスワードリセットトークン、API key — これらに UUID v4 を使うコードは今でもよく見かける。動くし衝突もしない、だから OK というわけにはいかない。OWASP は 専用の暗号学的乱数 (Python の secrets、Node の crypto.randomBytes、Go の crypto/rand) でトークンを生成することを明示している。UUID は「ユニーク識別子」であって「秘密のトークン」ではない、というのが原則だ。
Every UUID V4 の面白さは、ゲーマー的な無謀さと UI の妙にある。だが副産物として、UUID という言葉に込められた 「ユニーク」「衝突しない」 のオーラを、「秘密」「予測不能」 と無自覚に混ぜている開発文化を炙り出してもいる。次に認証コードを書くとき、Uuid::uuid4() を呼ぶ前に 本当に CSPRNG が必要な場面ではないか を一度立ち止まって考えたい。
COMMENTS 0
No comments yet — be the first to leave one.