JWT を localStorage に置くな問題 ─ 受託で診る Web 認証実装セキュリティ監査 | GH Media
URLがコピーされました

JWT を localStorage に置くな問題 ─ 受託で診る Web 認証実装セキュリティ監査

URLがコピーされました
JWT を localStorage に置くな問題 ─ 受託で診る Web 認証実装セキュリティ監査

2026 年 5 月、「JWT を localStorage に置くな」はなぜ言われるのか、Cookie 回帰までの時系列整理(Zenn 2026-05-27) という記事がトレンド入りしました。発端は Web セキュリティの第一人者・徳丸浩氏の X 投稿で、JWT を localStorage に保存する SPA の設計が XSS に対して脆弱であるという指摘です。記事は、Authorization ヘッダ方式が一時的に主流になった経緯と、近年再び HttpOnly Cookie によるセッション方式へ「回帰」しつつある時系列を丁寧に整理しています。

弊社では受託で 「既存 Web アプリ / SPA の認証実装を点検してほしい」という相談が増えています。多くは「動いてはいるが、トークンの保存場所やリフレッシュ設計が本当に安全なのか自信がない」というものです。本記事では、こうした不安を 「Web 認証実装セキュリティ監査」という受託サービスに落とし込み、診断から是正、継続運用までの進め方を整理します。基礎的な脅威モデルは Web セキュリティ入門 を、認証基盤そのものの乗り換えは Better Auth / Supabase / Clerk への認証移行受託 を併せてご覧ください。

なぜ「トークン保存場所が分水嶺」なのか

議論の核心は 「アクセストークンをどこに置くか」です。localStorage は JavaScript から自由に読める一方、HttpOnly Cookie はスクリプトから不可視です。この一点が XSS 耐性を大きく分けます。

観点localStorage 保存 + Authorization ヘッダHttpOnly Cookie + 適切なフラグ
XSS でのトークン窃取JS から読めるため漏えいしやすいHttpOnly で JS から読めず窃取困難
CSRFヘッダ付与のため原理的に起きにくいSameSite=Lax/Strict + CSRF トークンで対策必要
サードパーティ Cookie 規制影響を受けにくいクロスサイト利用は要注意(ファーストパーティ前提)
クロスオリジン API 呼び出しCORS 設定で比較的素直ドメイン設計・SameSite 調整が必要
実装難易度一見簡単だが XSS 対策が前提条件サーバ側セッション / BFF が要るが堅牢

重要なのは 「どちらかが万能ではない」ことです。localStorage 方式でも CSP やサニタイズで XSS を封じれば運用できますが、XSS が一度でも刺さればトークンが丸ごと抜かれるという単一障害点を抱えます。一方 Cookie 方式は CSRF 対策と SameSite の設計を正しく行うことが前提です。監査では「自社の脅威モデルに対してどちらの前提条件を満たせているか」を起点に判断します。

受託案件で活きる 3 つの構造変化

構造 1: 「動けばよい」から「脅威モデル前提の認証設計」へ

かつては「ログインできれば OK」でしたが、今は XSS / CSRF / オープンリダイレクトを脅威モデルとして明示し、それぞれに対策が紐づいているかが問われます。受託では、要件定義の段階で脅威モデルを文書化し、設計判断の根拠を残すことが価値になります。脅威の洗い出し方は Web セキュリティ入門 の整理が出発点として有効です。

構造 2: フロント単体から BFF・Cookie セッション回帰へ

SPA がフロント単体でトークンを抱える構成から、BFF(Backend for Frontend)がトークンを保持し、ブラウザには HttpOnly Cookie のセッション ID だけを渡す構成への揺り戻しが進んでいます。受託では「既存 SPA を壊さずに BFF を差し込む」段階的移行の設計力が差になります。

構造 3: 単発診断から継続的なセキュリティ運用へ

依存ライブラリの脆弱性やサードパーティスクリプトは日々変化します。一度診断して終わりではなく、継続的に再監査する運用へのニーズが高まっています。評価の枠組みは SCS(セキュリティ評価)ガイド の考え方を採り入れ、定点観測できる形に落とします。

受託で提供する「Web 認証実装セキュリティ監査」5 フェーズ

フェーズ 1: 現状診断

  • トークン保存箇所の棚卸し(localStorage / sessionStorage / Cookie / メモリ)
  • 認証フロー図化(ログイン・リフレッシュ・ログアウト・失効)
  • 使用ライブラリ・バージョン・既知脆弱性の確認

フェーズ 2: 脅威評価

  • XSS / CSRF / オープンリダイレクト / トークン固定化の点検
  • CSP・SameSiteHttpOnlySecure フラグの現状確認
  • リフレッシュトークンの有効期限・ローテーション・失効方式の評価

フェーズ 3: 是正設計

  • トークン保存方式の方針決定(Cookie セッション / BFF 導入の要否)
  • CSP 設計(nonce / strict-dynamic の採否)
  • リフレッシュトークンローテーションと失効リスト設計

フェーズ 4: 是正実装・PR レビュー

  • 是正コードの実装または既存 PR のレビュー
  • SameSite / HttpOnly / Secure 設定の反映確認
  • 自動テスト(認証フロー・失効・CSRF)の追加

フェーズ 5: 再監査・運用(継続)

  • 是正後の再診断と差分確認
  • 依存ライブラリ・CSP 違反レポートの定点観測
  • インシデント時の失効・ローテーション手順の整備

受託向け技術スタック標準セット

レイヤ推奨代替
認証方式サーバセッション + BFFOIDC / OAuth 2.1(外部 IdP)
トークン保存HttpOnly + Secure + SameSite Cookieメモリ保持(短命アクセストークン)
CSP / ヘッダCSP(nonce ベース)+ HSTS + X-Content-Type-Optionsreport-only から段階導入
CSRF 対策SameSite + Double Submit / Synchronizer TokenOrigin / Referer 検証併用
監査・検査ツール依存脆弱性スキャン + DAST + CSP レポート収集手動コードレビュー併用

ツールはあくまで補助で、「脅威モデルに沿った設計判断」が主役である点は変わりません。

どの案件に必要か / 不要か

監査が必要なケース監査が過剰なケース
SPA で localStorage にトークンを置いている静的サイトで認証機能がない
個人情報・決済情報を扱う社内クローズドな検証用ツール
リフレッシュトークンの設計が曖昧フルマネージド IdP に全面委譲済みで自前実装が皆無
サードパーティスクリプトを多数読み込む公開済みの読み取り専用コンテンツのみ

受託契約に書く 6 つの条項

条項内容顧客が確認すべきこと
診断範囲対象アプリ・ドメイン・除外範囲の明記サブドメインや外部 API が範囲内か
検査方法静的・動的・手動の手法と非破壊の取り決め本番環境での実施可否
是正責任の分界報告のみか実装まで含むか自社改修分との線引き
再現データの扱い取得した認証情報・PoC の保管と破棄機密保持と保存期間
重大脆弱性の通知緊急度に応じた即時報告フロー連絡経路と SLA
再監査の条件是正後の再診断の範囲と回数追加費用の有無

価格モデル — Web 認証セキュリティ監査パッケージ

プラン形態価格レンジ(税別)対象
スポット診断一括80 万円〜単一アプリの認証実装を一度点検
Lite月額8 万円〜小規模・定点観測のみ
Standard月額20 万円〜継続監査 + 月次レポート
Enterprise月額50 万円〜複数アプリ・BFF 運用・SLA 付き
是正実装一括60 万円〜診断後の是正コード実装

金額は規模・対象数・本番環境の制約により変動するため、最終的には個別見積りとなります。

顧客側 ROI 試算

効果試算の考え方
情報漏えいインシデント回避漏えい時の対応・通知・賠償コストの回避
是正の手戻り削減リリース前是正により本番改修コストを圧縮
脆弱性診断対応工数診断指摘の都度対応を月次運用で平準化
取引先の信頼維持BtoB の継続取引・与信維持に寄与

仮にスポット診断 + 是正実装で初期 140 万円程度を投じても、一度の重大インシデント対応コスト(調査・通知・補償・信頼失墜)に比べれば桁が小さいことが多く、対象が個人情報や決済を扱うアプリであれば、回避できる損失額の期待値で十分に回収できる水準に収まります。

ハマりやすい 5 つの落とし穴

保存場所を変えても、SameSite や CSRF 対策が伴わなければ別のリスクに付け替わるだけです。移行は対策セットで行います。

落とし穴 2: CSP を未設定のまま放置する

XSS の最後の防壁である CSP がないと、localStorage だろうと Cookie だろうとスクリプト注入の被害が広がります。report-only から段階導入するのが現実的です。

落とし穴 3: リフレッシュトークンを実質無期限にする

長命なリフレッシュトークンは窃取時の被害が甚大です。ローテーションと失効リストを設計に含めます。

落とし穴 4: SPA 前提のまま BFF を導入しない

フロントにトークンを持たせ続ける限り XSS の射程に入ります。機微情報を扱うなら BFF でトークンを隠す選択を検討します。

落とし穴 5: サードパーティスクリプトを放置する

広告・解析・チャットなどの外部スクリプトは XSS の侵入口になり得ます。読み込み元の棚卸しと CSP での許可制御が必要です。

90 日アクションプラン

取り組み
第 1〜2 週トークン保存箇所の棚卸し・認証フロー図化
第 3〜4 週XSS / CSRF / オープンリダイレクトの脅威評価
第 5〜6 週CSP・SameSiteHttpOnly の現状確認と是正方針決定
第 7〜9 週是正実装・PR レビュー・テスト追加
第 10〜11 週BFF / Cookie セッション移行の段階適用
第 12〜13 週再監査・定点観測の運用化・引き継ぎ

まとめ

「JWT を localStorage に置くな」という議論は、「保存場所を変えれば解決」という単純な話ではなく、脅威モデルに沿って認証設計全体を見直すべきという問いかけです。HttpOnly / Secure / SameSite / CSP / リフレッシュトークン設計 / BFF を一体で捉えれば、localStorage と Cookie のどちらを選ぶにせよ、前提条件を満たしているかが判断軸になります。弊社の Web 認証実装セキュリティ監査は、この判断を診断・是正・継続運用まで伴走してかたちにします。既存アプリの認証に少しでも不安があれば、お問い合わせフォーム からお気軽にご相談ください。

Sources

URLがコピーされました

グリームハブ株式会社は、変化の激しい時代において、アイデアを形にし、人がもっと自由に、もっと創造的に生きられる世界を目指しています。

記事を書いた人

鈴木 翔

鈴木 翔

技術の可能性に魅了され、学生時代からプログラミングとデジタルアートの分野に深い関心を持つ

関連記事