概要
Webアプリケーションのセキュリティは、セッション管理・同一オリジンポリシー(SOP)・コンテンツセキュリティポリシー(CSP)の正確な理解なしには成立しません。SC試験では、これらの仕組みとXSS・CSRFとの関係が問われます。
セッション管理
セッションIDの設計
HTTPはステートレスなプロトコルです。セッションIDでユーザを識別します。
安全なセッションID の要件:
- 十分な長さ(128ビット以上)
- 暗号的に安全な乱数で生成
- セッションごとに一意
- ログイン後に再生成(セッション固定攻撃の防止)
セッション固定攻撃
攻撃フロー:
1. 攻撃者がセッションIDを事前に取得(例:URL パラメータで指定)
2. 被害者がそのセッションIDでログイン
3. 攻撃者が既知のセッションIDで被害者のセッションを乗っ取る
対策:ログイン成功後に新しいセッションIDを発行する
Cookie のセキュリティ属性
| 属性 | 効果 |
|---|---|
| HttpOnly | JavaScriptからCookieを読み取り不可。XSS攻撃によるセッション窃取を防止 |
| Secure | HTTPS通信のみCookieを送信。HTTP平文通信での漏洩を防止 |
| SameSite=Strict | 同一サイト以外からのリクエストにCookieを送付しない。CSRF対策 |
| SameSite=Lax | 外部サイトからのGETリクエストには送付(トップレベルナビゲーション) |
| SameSite=None; Secure | クロスサイトでも送付(明示的に必要な場合のみ) |
セッションタイムアウト
| 種類 | 説明 |
|---|---|
| アイドルタイムアウト | 一定時間操作なしでセッション無効化 |
| 絶対タイムアウト | ログインから一定時間でセッション強制終了 |
SOP(Same-Origin Policy:同一オリジンポリシー)
定義
ブラウザのセキュリティ機能で、あるオリジンのJavaScriptが別オリジンのリソースにアクセスすることを制限します。
オリジン = プロトコル + ホスト + ポート番号
同一オリジン:
https://example.com/page1 と https://example.com/page2 → 同一
別オリジン:
https://example.com と https://api.example.com → 別(サブドメインが異なる)
https://example.com と http://example.com → 別(プロトコルが異なる)
https://example.com と https://example.com:8080 → 別(ポートが異なる)
CORS(Cross-Origin Resource Sharing)
SOPの例外としてのCORS
SOPはセキュリティには重要ですが、正規のクロスオリジン通信(フロントエンドとAPIサーバが別ドメイン等)も制限してしまいます。CORSはこれを安全に許可する仕組みです。
CORSの仕組み
シンプルなリクエスト(GETやシンプルなPOST):
ブラウザ → GETリクエスト(Origin: https://app.example.com)→ APIサーバ
APIサーバ → レスポンス(Access-Control-Allow-Origin: https://app.example.com)→ ブラウザ
プリフライトリクエスト(PUTやDelete・カスタムヘッダを使う場合):
ブラウザ → OPTIONSリクエスト(プリフライト)→ APIサーバ
APIサーバ → 許可設定を返す → ブラウザ
ブラウザ → 本来のリクエスト → APIサーバ
CORSの設定ミス
危険な設定:
Access-Control-Allow-Origin: * ← 全オリジンを許可
Access-Control-Allow-Credentials: true ← 認証情報も送信可能
(両方を同時に設定すると認証済みAPIが全オリジンから呼び出し可能になる)
安全な設定:
ホワイトリストで許可オリジンを明示
Access-Control-Allow-Origin: https://app.example.com
CSP(Content Security Policy:コンテンツセキュリティポリシー)
目的
XSS攻撃を軽減するHTTPレスポンスヘッダです。ブラウザが実行してよいリソースの発信元を制限します。
基本的なCSPヘッダ
Content-Security-Policy:
default-src 'self'; ← デフォルト:同一オリジンのみ
script-src 'self' https://cdn.example.com; ← スクリプトは自サイトとCDNのみ
style-src 'self' 'nonce-abc123'; ← スタイルは自サイトとnonce一致のみ
img-src 'self' data:; ← 画像は自サイトとdata URIのみ
frame-ancestors 'none'; ← iframeへの埋め込みを禁止(Clickjacking対策)
| ディレクティブ | 内容 |
|---|---|
default-src | 未指定のリソースのデフォルト |
script-src | JavaScriptの読み込み元 |
style-src | CSSの読み込み元 |
frame-ancestors | このページをiframeで埋め込めるオリジン |
report-uri | CSP違反をJSON形式で報告するエンドポイント |
CSP nonceとhash
インラインスクリプトをすべて禁止するとXSSは困難になりますが、正規のインラインスクリプトも実行できなくなります。nonceで正規のスクリプトのみを許可します。
<!-- サーバがリクエストごとにランダムなnonceを生成 -->
<script nonce="ランダムな値">
// このスクリプトのみ実行許可
</script>
SC試験での頻出ポイント
- HttpOnly Cookieの目的:JavaScriptからのCookie読み取りを防止してXSSによるセッション窃取を防ぐ
- SameSite=StrictとCSRFの関係:外部サイトからのリクエストにCookieが付かないためCSRFを防止
- CORSのプリフライトリクエスト:複雑なクロスオリジンリクエスト前にOPTIONSで許可確認
- CSPの役割:XSSが起きても許可されていないオリジンへのスクリプトアクセスをブロック
- SOPとCORSの関係:SOPでクロスオリジン通信を禁止し、CORSで安全に例外を許可する
よくある誤問・ひっかけパターン
誤り① 「CORSはCSRF対策になる」→ 誤。CORSはJavaScriptからのクロスオリジンのレスポンスを制限しますが、HTMLフォームのPOSTはCORSの対象外です。CSRFにはCSRFトークンやSameSite Cookieが必要です。
誤り② 「HttpOnly Cookieを使えばXSSは防げる」→ 誤。HttpOnlyはXSSによるセッション窃取を防ぎますが、XSS攻撃自体(DOM操作・偽フォーム表示等)は防げません。
誤り③ 「Access-Control-Allow-Origin: * は便利なので常に設定してよい」→ 誤。全オリジンからのAPIアクセスを許可してしまい、credentials: includeと組み合わせると特に危険です。
関連用語
- XSS(クロスサイトスクリプティング) — CSP・HttpOnlyで軽減
- CSRF(クロスサイトリクエストフォージェリ) — SameSite Cookieで防止
- セキュアコーディング — セッション管理の実装原則
重要キーワード
| 用語 | 説明 |
|---|---|
| セッション固定攻撃 | 攻撃者が指定したセッションIDでユーザをログインさせる攻撃 |
| HttpOnly | JavaScriptからCookieを読み取り不可にする属性 |
| SameSite | クロスサイトリクエスト時のCookie送付を制御する属性 |
| SOP | Same-Origin Policy。別オリジンのリソースへのアクセスをブロックするブラウザ機能 |
| CORS | SOPの例外として特定のクロスオリジン通信を安全に許可する仕組み |
| CSP | コンテンツセキュリティポリシー。実行可能なスクリプト・リソースの発信元を制限 |