はじめに
こんにちは。アメリカ在住で独学エンジニアを目指している Taira です。
SPA(Single Page Application)を開発する際、セキュリティ対策としてまず意識すべきは XSS(クロスサイトスクリプティング) と CSRF(クロスサイトリクエストフォージェリ) です。
この記事では、それぞれの仕組みや攻撃手法、そして SPA ならではの対策方法について整理します。
1. XSS とは?
XSS(クロスサイトスクリプティング)とは
悪意あるスクリプトを Web ページに仕込む攻撃です。
被害者のブラウザ上で不正な JavaScript が実行され、以下のような被害が起こります。
- 認証情報(トークン、Cookie)の窃取
- 偽フォームの表示やフィッシング
- 任意の API リクエスト送信
例
掲示板に <script>alert('hacked')</script> と入力できる脆弱性があった場合、
そのページを開いたユーザーのブラウザでスクリプトが実行されます。
2. CSRF とは?
CSRF(クロスサイトリクエストフォージェリ)とは
ユーザーが意図しないリクエストを送らせる攻撃です。
ログイン済みのユーザーが攻撃者のサイトを開いた際、攻撃者が用意したリクエストが自動的に Cookie を伴って送信され、被害者のアカウントで操作が行われます。
例
被害者が bank.com にログインした状態で、攻撃者が仕込んだページを開くと:
<img src="https://bank.com/transfer?to=attacker&amount=100000" />
このようなリクエストが自動送信され、意図せず送金されることがあります。
3. SPA における特徴
LocalStorage 認証の場合
- トークンを LocalStorage に保存し、リクエストヘッダーに手動で付与。
- CSRF 攻撃は成立しにくい(攻撃者のサイトから LocalStorage を読めないため)。
- XSS には弱い(XSS があると LocalStorage 内トークンが即盗まれる)。
Cookie 認証の場合
- HttpOnly CookieであればXSS に強い(JS から Cookie を読めない)。
- ただしCSRF に弱い(Cookie が自動送信されるため CSRF 対策が必須)。
4. XSS 対策
フロントエンド(React)の対策
-
dangerouslySetInnerHTMLを避ける(どうしても使う場合は DOMPurify でサニタイズ) -
外部データのエスケープ(React はデフォルトでエスケープする)
-
CSP(Content Security Policy)の設定
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; object-src 'none';" /> -
外部スクリプトや CDN のドメインを制限
以下のサイトがとても分かりやすく CSP の設定方法を書いていたので載せておきます
バックエンド(Rails API)の対策
- JSON レスポンスには基本的に XSS の危険性は低いが、HTML 返却時はエスケープ必須
5. CSRF 対策
LocalStorage 認証の場合
- CSRF は原理的に発生しづらい(攻撃者ページはトークンを送れないため)
- 代わりにXSS 対策を強化することが重要
Cookie 認証の場合
-
SameSite=LaxまたはSameSite=Strictを付与(クロスサイト送信を防止) -
CSRFトークンを用いた二重送信チェック -
Secure+HttpOnlyを必ず付与
まとめ
- XSS: 不正スクリプトを実行させてトークンや情報を盗む攻撃
- CSRF: 自動送信される Cookie を悪用して不正操作する攻撃
- LocalStorage 認証は CSRF に強いが XSS に弱い
- Cookie 認証は XSS に強いが CSRF に弱い
- SPA では構成に合わせて優先的に対策すべき脆弱性が異なる
参考資料