JWTは「封書」ではなく「ハガキ」だ:機密情報漏洩の構造とJWEによる防衛戦略
多くの開発者がJWT(JSON Web Token)を「セキュアな認証トークン」と誤解している。しかし、現実のインシデント現場において、JWTはしばしば「宝の地図」と化している。署名(JWS)によって改竄は防げても、ペイロードがBase64エンコードされているだけの「可読な平文」であることを忘れてはならない。
本稿では、JWTの設計上の盲点と、それに対するJWE(JSON Web Encryption)による防衛アーキテクチャについて、現場の知見を交えて深掘りする。
—
1. なぜJWTに機密情報を入れてはならないのか
JWTを構成する3つのパート、Header・Payload・Signatureのうち、Payloadは単にBase64Urlエンコードされているに過ぎない。パケットキャプチャやブラウザのデベロッパーツール、あるいはログ収集基盤を覗けば、誰でも中身を瞬時にデコードできる。
攻撃者の視点:IDORのトリガーとなる「メタデータ」
かつて私が調査したあるSaaSのインシデントでは、JWTのペイロードに tenant_id や internal_role_flag が含まれていた。攻撃者はこれをデコードし、自身の権限を書き換えて署名を再計算(あるいは脆弱な実装であれば alg: none を悪用)することで、他テナントの情報を列挙するIDOR(Insecure Direct Object Reference)を完遂させた。
教訓: JWTに含めて良いのは「トークンを検証するための最小限の識別子(sub や iat など)」のみである。認可判定に必要な属性(Attribute)は、トークンではなく、セキュアなバックエンドのセッションストアやデータベースからフェッチすべきだ。
—
2. JWE(JSON Web Encryption)の適用判断:いつ暗号化すべきか
どうしてもクライアント側に機密情報を持たせなければならない、あるいはオフライン環境での検証が必要な場合、JWS(署名)だけでは不十分だ。ここで登場するのがJWEである。
JWEの構造とオーバヘッド
JWEはペイロードを暗号化し、かつ署名する仕組みだ。これにより、第三者はパケットを傍受しても中身を解読できず、かつ改竄も検知できる。
しかし、JWEを導入する際は以下のトレードオフを計算する必要がある。
1. 計算リソース: 非対称暗号(RSAやECDH)のオーバーヘッドは、高負荷なマイクロサービスでは無視できない遅延を生む。
2. キー管理: 暗号鍵のライフサイクル管理は、署名鍵よりも遥かに複雑だ。鍵のローテーション(Key Rollover)をミスれば、全ユーザーが即座にログアウトする事態を招く。
JWEの実装例(Node.js / joseライブラリ)
import { EncryptJWT, generateKeyPair } from ‘jose’;
// 鍵ペアの生成(実運用ではKMS等からロードすること)
const { publicKey, privateKey } = await generateKeyPair(‘RSA-OAEP-256’);
// JWEの生成
const jwt = await new EncryptJWT({ ‘sensitive_data’: ‘confidential_info’ })
.setProtectedHeader({ alg: ‘RSA-OAEP-256’, enc: ‘A256GCM’ }) // 暗号化アルゴリズムの指定
.setIssuedAt()
.setIssuer(‘urn:example:issuer’)
.setExpirationTime(‘2h’)
.encrypt(publicKey); // 公開鍵で暗号化
console.log(jwt);
—
3. 次世代の脅威への備え:耐量子暗号(PQC)の影
今、セキュリティアーキテクトが無視できないのは、将来的な「Store Now, Decrypt Later」攻撃だ。現在のJWTで使われるRSAやECDSAは、量子コンピュータの台頭によって解読されるリスクがある。
今後数年以内に、JWTの署名および暗号化スキームは、NISTが標準化を進める耐量子暗号アルゴリズム(CRYSTALS-Dilithiumなど)への移行を検討しなければならない。特に、長期的な機密性を担保する必要があるデータを含むトークンにおいて、この移行は喫緊の課題となる。
—
4. 現場の防衛アーキテクチャ設計:ガードレイルの構築
最後に、チーフホワイトハッカーとして推奨する防御のベストプラクティスを提示する。
- データ分離の原則: JWTには「誰が(Subject)」というIDのみを格納し、「何ができるか(Policy)」はサイドカープロキシやAPIゲートウェイ側でOPA(Open Policy Agent)等を用いて判定せよ。
- ガードレイルの設定: 生成AI等の自動化ツールがコードを生成する際、JWTペイロードにオブジェクトを直接詰め込むようなコードを弾く「静的解析ルール(Semgrep等)」をCI/CDパイプラインに組み込むこと。
- 通信の堅牢化: JWEを導入しても、TLS 1.3の強制は必須だ。TLS終端でのパケット解析と、WAFでのJWTの構造異常検知(異常な長さ、アルゴリズムの不整合)を多層防御として実装せよ。
結論
JWTのセキュリティは「仕様を正しく理解すること」から始まる。機密情報を運ぶための封筒としてJWTを使うことは、ハガキに現金を同封するようなものだ。もし機密性を担保する必要があるなら、即座にJWEへの移行を検討するか、あるいはその設計自体を疑うべきである。
セキュリティとは、技術の適用ではなく、リスクの最小化という哲学である。設計の段階でその哲学を欠けば、どんなに強力な暗号アルゴリズムも、単なる「気休め」に過ぎない。
コメント