XSS の4つの侵入経路と多層防御モデル

Web アプリの XSS はどこから入るか — 4 つの侵入経路と多層防御モデル

「Reactは自動エスケープしてくれるからXSSは古い話」——そう思っていないでしょうか。 実際には、ReactやNext.jsが標準で塞いでくれる経路は XSS の侵入口の一部 にすぎません。dangerouslySetInnerHTML、依存パッケージの汚染、悪意ある拡張機能。これらはReactの自動エスケープを そもそも経由しません。 この記事では、現代のWebアプリでXSSが侵入してくる 4 つの経路 を整理し、それぞれに対する 多層防御モデル をマトリクス化します。最後に、認証トークンの保存設計(better-authのAccess Tokenを例に)を取り上げて、「攻撃経路 × 防御層」で判断する具体例を示します。 この記事を書いたきっかけ 3サイトのフロントエンドを並行開発する中で、リリース運用フェーズへの移行に合わせて認証セキュリティ設計を見直しました。実装を読み込むと、「Access Tokenに5分のTTLを設定しているから安全」という直感は持続的XSSのケースでは成り立たないと気づきました。第1号「NextAuth v5 から better-auth へ!逆引き移行チートシート」で扱った認証基盤の続編として、運用フェーズで考えるべき多層防御の整理を共有します。 先に結論:攻撃経路 × 防御層のマトリクス 詳細は本文で展開します。結論は次のマトリクスに集約されます。 Stored Reflected DOM-based サプライチェーン 拡張機能 CSP ◎ ◎ ◯ △ × レート制限 △ △ △ × × トークン隔離 △ △ △ × × 異常検知 △ △ △ △ △ 読み取り: CSP が最も広く効く根本対策。ただしサプライチェーンと拡張機能には限界がある 認証トークン隔離(BFF化)の効果は限定的で、AT 値漏洩経路は塞ぐが、API 不正コール経路は塞げない 単独の銀の弾丸はなく、組み合わせる前提で設計する なぜこのマトリクスになるのか、なぜトークン隔離だけでは不十分なのかを、以下で順に解説します。 この記事で得られること XSSの 4 つの侵入経路(Stored / Reflected / DOM-based / サプライチェーン・拡張機能)の整理 「持続的 XSS」という概念と、それが短命トークンを無効化する仕組み CSP / レート制限 / 認証トークン隔離 / エラー監視 の4つの守備範囲を比較した防御マトリクス 認証トークンを JS から隠す設計 が「何を防げて、何を防げないか」 単一の銀の弾丸ではなく、多層で組み合わせる ための判断軸 動作確認環境 種別 バージョン OS macOS 15.x Node.js 24.x パッケージマネージャー pnpm 10.x Next.js 16.x(App Router) React 19.x better-auth 1.x 1. なぜ XSS が今も現役なのか XSS(Cross-Site Scripting)は2000年代から続く古典的な脆弱性です。ReactやVueのような現代のフレームワークは、テンプレート内の変数を自動的にエスケープしてくれます。 ...

2026年6月3日 · 読了時間: 7分 · 福士宗介
NextAuth to better-auth migration

【Next.js App Router】NextAuth v5 から better-auth へ!逆引き移行チートシート

(2026/6/9追記) 本記事の公開後にセキュリティ運用の見直しを行い、§2と §4にそれぞれ追記を加えています。最新の推奨構成は各セクションの追記をご確認ください。(追記ここまで) Better Auth が Auth.js を公式に引き継いだ発表 2025年9月付近で、Auth.js(旧NextAuth.js、以下NextAuth)の公式発表がありました。Better Auth(npmパッケージ名: better-auth、以下better-auth)チームに引き継がれるという内容です。 発表された概要は以下のとおりです。 Auth.jsのセキュリティ修正やクリティカルな対応は継続される 新機能・今後の進化は Better Auth 側に集約される NextAuthの開発メンバーが関わる形でBetter Authへ収束していく方針です。 既存のプロジェクトであればすぐさまbetter-authに切り替える必要はありませんが、新規のプロジェクトであればbetter-authも有力な選択肢です。 今回、新規プロジェクトの立ち上げにあたり、この公式発表を受けてbetter-authを採用しました。NextAuth v5では jwt コールバックにリフレッシュ処理を集約していましたが、ロジックの肥大化により保守が困難になっていました。better-authのプラグインベースの設計に魅力を感じたことも決め手の1つです。 このドキュメントは、Next.js App Router と TanStack Query を採用したプロジェクトを対象としています。バックエンドAPIが「JWT + リフレッシュトークン」を発行するステートレスな構成において、NextAuth (v5) からbetter-authへ移行する際のノウハウを逆引き形式でまとめました。 これからbetter-authの導入や移行を検討しているエンジニアの方は、ぜひ参考にしてください。 動作確認環境 ライブラリ バージョン Next.js 16.0.7 React 19.x better-auth 1.4.18 @tanstack/react-query 5.75.4 Node.js 24.11.1 1. 初期設定・ルーティング編 Q. フロントエンドでセッション情報を共有したい(Providerの配置) NextAuth: ルートレイアウトなどに <SessionProvider> を配置してReact Contextでセッションを共有する必要がありました。 better-auth: Providerは一切不要(削除)です。better-authはCookieベースで動作し、内部的に nanostores のAtomを利用して各コンポーネントに状態を共有します。 補足: なぜ Provider なしで動くのか? NextAuthはReact Context(Provider → Consumer)でセッションを配信していました。better-authはReactの外にあるグローバルストア(nanostoresのAtom)にセッション状態を保持し、useSession() はそのAtomをsubscribeするだけです。Reactツリーに依存しないためProviderが不要になります。初回マウント時にCookieから /api/auth/get-session をfetchしてAtomを初期化し、以降はAtomの値を返します。 ...

2026年4月10日 · 読了時間: 4分 · 福士宗介