🎯 1. はじめに
Webアプリ開発において絶対に押さえておきたい攻撃が XSS(クロスサイトスクリプティング) と CSRF(クロスサイトリクエストフォージェリ) です。
この2つは名前が似ていますが、攻撃の仕組みも、防ぎ方もまったく違います。
本記事では、初心者の方でも理解しやすいように、例を交えながら解説します。
🎯 2. この記事でわかること
-
XSSとは何か
-
CSRFとは何か
-
なぜ起こるのか
-
どうやって防ぐのか
-
各技術(Next.jsやDjango、API開発)で意識すべき点
✨ 3. まず結論:XSSとCSRFの違い
| 攻撃名 | 何が起きる? | 原因 | 防ぎ方 |
|---|---|---|---|
| XSS | 悪意あるスクリプトが実行される | 入力値をそのまま表示 | HTMLエスケープ、CSP、HttpOnly Cookie |
| CSRF | ユーザーが意図しない操作をされる | ブラウザが自動でCookieを送る性質 | CSRFトークン、SameSite Cookie、認証方式の工夫 |
🧨 4. XSS(クロスサイトスクリプティング)とは?
🔎 XSSの仕組みを簡単に説明すると…
ユーザーから送られたデータを、そのまま 「Web ページに表示してしまう」と発生します。
【例】危険な掲示板アプリ
ユーザーがコメント欄にこのような文字を入力すると…
<script>alert('あなたのクッキーいただき!')</script>
入力値をそのままレンダリング(画面に描画すること)してしまうコードだと JavaScript が実行されてしまいます。
これが XSS(クロスサイトスクリプティング)攻撃 です。
<script> タグで囲まれた部分は、HTMLでは "表示" ではなく “JavaScriptとして実行” されます。
そのため、ユーザー入力をそのまま表示すると、意図しないスクリプトが動いてしまう危険があります。
👿 XSSで何がされるの?
-
Cookieの盗み見(セッションIDを盗む)
-
偽フォームの表示
-
悪意あるページへ誘導
-
ログイン情報の奪取
など非常に危険です。
🛡 XSSの対策方法
① HTMLエスケープ(最重要)
「<」 を < に置き換えるなど、タグ として動かないようにすること。
つまり・・・
“危険な記号を安全な文字に置き換えて、スクリプトが実行されないようにする仕組み”
それがエスケープ処理です。
-
Django → 自動でエスケープ(safe を使わない限り)
-
React/Next.js → デフォルトで安全(dangerouslySetInnerHTML は危険)
Vue.jsやRuby on Railsも同様です。
② HttpOnly Cookie を使う
JavaScriptからCookieを読めなくする 👉 Cookie盗難が困難に
③ CSP(Content Security Policy)
信用できないスクリプトの実行を防ぐレスポンスヘッダ。
例:
Content-Security-Policy: default-src 'self';
この意味は「同じドメインから読み込んだものだけ実行してOK。他サイトのスクリプトや画像、CSS は全部ダメ!」ということです。
例として、サイトのアドレスが https://example.com だったとします。
その場合は、下記の通りとなります。
| 読み込み先 | 内容 | 実行される? |
|---|---|---|
| https://example.com/js/app.js | 自サイトのJS | ▶ 実行OK |
| https://example.com/style.css | 自サイトのCSS | ▶ OK |
| https://cdn.examplecdn.com/script.js | 外部CDNのJS | ❌ 実行NG |
| https://malicious-hacker.com/hack.js | 攻撃者のJS | ❌ 完全にブロック |
他サイトのスクリプトは、一切動かなくなる = XSSの成功率が劇的に下がる。
XSS攻撃の多くは、攻撃者が作った JavaScriptファイルを読み込ませたり
<script src="https://悪いサイト/hack.js"></script>
<img src onerror="悪意あるスクリプト">
など 外部の悪意あるスクリプト を実行させることが目的です。
しかし、CSP によって…
「外部サイトのスクリプトは 全部禁止」
というルールを入れてしまうと、攻撃者が何を仕掛けても、ブラウザ側が これ読んじゃダメだよ! と自動でブロック します。
🎯 5. CSRF(クロスサイトリクエストフォージェリ)とは?
🔎 CSRFの仕組みを簡単に説明すると…
ユーザーがログイン中であることを悪用した攻撃 です。
ユーザーがログインしている別サイトに対して、攻撃者が 「勝手にリクエストを送らせる」 ことが目的です。
【例】SNSにログイン中のユーザー
攻撃者が作った悪意あるページにアクセスすると、
裏でこのようなリクエストを送られます:
POST https://sns.example.com/post
Cookie: sessionid=ユーザーのセッション
ブラウザは「同じサイトの Cookie を自動で送る仕様」なので、本人の代わりに投稿されてしまう ことがあります。
👿 CSRFで何がされるの?
-
本人になりすまし投稿
-
パスワード変更
-
商品購入
-
アカウント削除
など、「POST / DELETE 系操作」が狙われます。
🛡 CSRFの対策方法
① CSRFトークン方式(鉄板)
-
Django は標準で有効
-
SPA + API でも実装可能
リクエストごとに「ランダムなトークン」を確認し、攻撃者が再現できないようにする仕組み。
② SameSite Cookie を設定する
Cookieに以下属性を付ける:
Set-Cookie: sessionid=xxx; SameSite=Lax;
意味:
「他サイトからのPOSTリクエストではCookieを送らない」
最近のブラウザではデフォルトで有効。
③ 認証方法を工夫する(API開発向け)
例えば、
-
JWTのHttpOnly Cookie + SameSite=Lax
-
トークンベースでAPIアクセスを行う
-
二段階認証
これも CSRF を弱体化できるポイント。
JWTやトークンについては、下記の記事で解説しています
🧩 6. XSSとCSRFは全く違う攻撃!
よく間違われるので、最後に要点まとめ:
| 項目 | XSS | CSRF |
|---|---|---|
| 悪用されるポイント | HTMLの表示 | 認証されたCookie |
| 何が起きる? | スクリプトが実行される | 意図しない操作が実行される |
| 原因 | 入力値の未エスケープ | ブラウザの自動Cookie送信 |
| 主な対策 | エスケープ + CSP | CSRFトークン + SameSite Cookie |
💡 7. Next.js / Django を使う場合の具体的ポイント
🔸 Next.js / React
-
dangerouslySetInnerHTML は極力使わない
-
Cookie に JWT を保存する場合は HttpOnly + SameSite
-
API Route を使う場合も CSRF 対策を意識
🔸 Django / DRF
-
csrf_token が標準で提供される
-
Djangoテンプレートは自動エスケープ
-
APIでセッション認証を使うときは CSRF 対策が必要
-
JWT運用では SameSite + HttpOnly が効果的
📌 8. まとめ
-
XSS → スクリプトが勝手に実行される攻撃
-
CSRF → Cooki情報を使って勝手に操作される攻撃
原因も対策も異なるため、両方セットで理解することが重要です。
Next.js や Django を使った開発でも頻繁に出てくるので、この記事が理解の助けになれば幸いです。
🏁 9. おわりに
最後までご覧いただきありがとうございました。これからもいろいろな初心者向けの記事を作成していきますでの、よろしくお願いします。
よかったら他の記事もご覧いただけると嬉しいです。今後もよろしくお願いいたします。