Skip to Content
ドキュメントWebコースReactの基本🔒 XSSを理解して対策する

🔒 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>
  )
}
javascript

app/vulnerable/page.js を作成し、以下の文字列を入力欄に貼り付けて「投稿」を押してみましょう。

<script>alert('XSS攻撃! Cookie: ' + document.cookie)</script>
plaintext

または

<img src="x" onerror="alert('XSS!')" />
plaintext

alert が表示されれば、XSSが成功しています。
実際の攻撃では alert の代わりにCookieを外部サーバーに送信するコードが入ります。


Reactのデフォルトはすでに安全

実は、Reactはデフォルトで自動的にエスケープを行うので、通常の書き方では XSS は起きません。

// ✅ 安全(Reactが自動でエスケープする)
function SafeComponent({ userInput }) {
  return <div>{userInput}</div>
}
javascript

<script>alert('XSS')</script> という文字列を渡しても、Reactは <&lt; に変換するため、スクリプトとして実行されません。


危険なパターン:dangerouslySetInnerHTML

dangerouslySetInnerHTML は名前の通り危険です。HTMLをそのまま挿入するため、XSSのリスクがあります。

// ❌ 危険:ユーザー入力をそのまま渡している
<div dangerouslySetInnerHTML={{ __html: userInput }} />
 
// ✅ 安全:DOMPurifyでサニタイズしてから使う
import DOMPurify from 'dompurify'
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
javascript

dangerouslySetInnerHTML を使う必要がある場面(たとえばブログ記事のHTMLを表示するなど)では、必ず**サニタイズ(無害化)**してから使いましょう。

DOMPurify のインストール

npm install dompurify
bash

対策まとめ

状況対応
通常の文字列表示{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>
}
javascript

確認しよう

  • dangerouslySetInnerHTML を使った脆弱なページを作り、スクリプトが実行されることを確認した
  • 通常の {userInput} ではスクリプトが実行されないことを確認した
  • XSSとは何かを自分の言葉で説明できる
  • dangerouslySetInnerHTML を安全に使う方法がわかる

AIに聞いてみよう

「CSP(Content Security Policy)とは何ですか?XSSの対策としてどのように使いますか?」


次のステップ

React セクションはここで完了です!次はスタイリングを学びましょう。

Tailwind CSSでスタイリング

Last updated on