Nuxt / SvelteKit すべてに共通する SSR の典型パターン JSON 文字列のエスケープを忘れると XSS の入り口になる 問題: ユーザー入力を含む JSON を <script> タグ内にそのまま埋め込むと、 入力に紛れ込んだ </script> で <script> タグが途中で閉じられ、 その後ろが新しいスクリプトとして実行されてしまう 脆弱なコード例 // SSR:サーバーで HTML を組み立てる const userInput = '</script><script>alert(1)</script>'; // 生成される HTML const html = ` <script> window.<_STATE<_ = { name: "${userInput}" }; </script> `; 問題点: • 入力中の </script> を HTML パーサが終了と判定 • 続くコードが新しい script タグとして実行される • ブラウザは JSON の中身を理解せず HTML として処理 対策:< と > を Unicode エスケープに変換 // 対策:Unicode エスケープに変換 const safeJSON = JSON.stringify(state) .replace(/</g, '\\u003c') .replace(<>/g, '\\u003e'); // 生成される HTML consthtml = ` <script> window.<_STATE<_ = ${safeJSON}; </script> `; 安全な理由: • \u003c はタグの開始と認識されず安全に処理される • JSON.parse は \u003c を < として正しく復元できる • React, Vue, Svelte 等の主要フレームワーク共通の対策 B-06 / 10 #fec_nagoya