🔒 XSSを理解して対策する
このページで学ぶこと
- XSS(クロスサイトスクリプティング)とは何かがわかる
- 実際に攻撃を体験して危険性を実感できる
- Reactで安全にHTMLを扱う方法がわかる
XSSとは
XSS(Cross-Site Scripting) は、悪意のあるJavaScriptをWebページに埋め込む攻撃です。
攻撃者が用意した <script> タグをページに実行させることで、以下のような被害が起きます。
- ユーザーのCookie(ログイン情報など)を盗む
- フィッシングサイトへリダイレクトする
- ページの内容を書き換えてニセの情報を表示する
攻撃を体験してみよう
脆弱なコードを書く
まずわざと脆弱なコードを書いて、XSSがどう起きるか体験しましょう。
// ⚠️ app/vulnerable/page.js(脆弱なコード)
'use client'
import { useState } from 'react'
export default function VulnerablePage() {
const [input, setInput] = useState('')
const [comment, setComment] = useState('')
const handleSubmit = () => {
setComment(input)
}
return (
<div>
<h1>コメント投稿(脆弱バージョン)</h1>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="コメントを入力"
style={{ width: '400px' }}
/>
<button onClick={handleSubmit}>投稿</button>
<h2>投稿されたコメント:</h2>
{/* ❌ dangerouslySetInnerHTML はHTMLをそのまま挿入する!危険! */}
<div dangerouslySetInnerHTML={{ __html: comment }} />
</div>
)
}app/vulnerable/page.js を作成し、以下の文字列を入力欄に貼り付けて「投稿」を押してみましょう。
<script>alert('XSS攻撃! Cookie: ' + document.cookie)</script>または
<img src="x" onerror="alert('XSS!')" />alert が表示されれば、XSSが成功しています。
実際の攻撃では alert の代わりにCookieを外部サーバーに送信するコードが入ります。
Reactのデフォルトはすでに安全
実は、Reactはデフォルトで自動的にエスケープを行うので、通常の書き方では XSS は起きません。
// ✅ 安全(Reactが自動でエスケープする)
function SafeComponent({ userInput }) {
return <div>{userInput}</div>
}<script>alert('XSS')</script> という文字列を渡しても、Reactは < を < に変換するため、スクリプトとして実行されません。
危険なパターン:dangerouslySetInnerHTML
dangerouslySetInnerHTML は名前の通り危険です。HTMLをそのまま挿入するため、XSSのリスクがあります。
// ❌ 危険:ユーザー入力をそのまま渡している
<div dangerouslySetInnerHTML={{ __html: userInput }} />
// ✅ 安全:DOMPurifyでサニタイズしてから使う
import DOMPurify from 'dompurify'
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />dangerouslySetInnerHTML を使う必要がある場面(たとえばブログ記事のHTMLを表示するなど)では、必ず**サニタイズ(無害化)**してから使いましょう。
DOMPurify のインストール
npm install dompurify対策まとめ
| 状況 | 対応 |
|---|---|
| 通常の文字列表示 | {userInput} のまま使えば安全(Reactが自動エスケープ) |
| HTMLを表示したい | dangerouslySetInnerHTML + DOMPurify でサニタイズ |
| URLを動的に設定する | href={userUrl} は javascript: から始まるURLを弾く処理が必要 |
URLのXSS対策
// ❌ 危険
<a href={userUrl}>リンク</a>
// 攻撃者が userUrl = "javascript:alert('XSS')" を入れると実行される
// ✅ 安全
function SafeLink({ url }) {
// http:// または https:// で始まるURLのみ許可する
const safeUrl = url.startsWith('https://') || url.startsWith('http://')
? url
: '#'
return <a href={safeUrl}>リンク</a>
}確認しよう
-
dangerouslySetInnerHTMLを使った脆弱なページを作り、スクリプトが実行されることを確認した - 通常の
{userInput}ではスクリプトが実行されないことを確認した - XSSとは何かを自分の言葉で説明できる
-
dangerouslySetInnerHTMLを安全に使う方法がわかる
AIに聞いてみよう
「CSP(Content Security Policy)とは何ですか?XSSの対策としてどのように使いますか?」
次のステップ
React セクションはここで完了です!次はスタイリングを学びましょう。
Last updated on