
Cookie設定診断
CookieはWebアプリケーションのセッション管理の中核です。 Secure、HttpOnly、SameSite属性の設定状況を検査し、 セッションハイジャックやCSRF攻撃のリスクを診断します。
チェック項目
5つのCookie属性を診断
Secure フラグ
HTTPS通信でのみCookieを送信するフラグ。HTTP接続時にはCookieが送信されないため、中間者攻撃によるCookie傍受を防止します。
安全な設定
Set-Cookie: session_id=abc123; Secure危険な設定
Set-Cookie: session_id=abc123 (Secureフラグなし)リスク
HTTP通信でCookieが平文で送信され、公共Wi-FiなどでセッションIDが傍受される。
HttpOnly フラグ
JavaScriptからのCookieアクセスを禁止するフラグ。XSS攻撃によるdocument.cookieを通じたセッションID窃取を防止します。
安全な設定
Set-Cookie: session_id=abc123; HttpOnly危険な設定
Set-Cookie: session_id=abc123 (HttpOnlyフラグなし)リスク
XSS脆弱性と組み合わせて、JavaScriptでセッションCookieが読み取られ、セッションハイジャックが成立する。
SameSite 属性
クロスサイトリクエスト時のCookie送信を制御する属性。CSRF(Cross-Site Request Forgery)攻撃の防止に効果的です。
安全な設定
Set-Cookie: session_id=abc123; SameSite=Lax危険な設定
Set-Cookie: session_id=abc123; SameSite=None (Secureなし)リスク
悪意のある外部サイトからのリクエストにCookieが付与され、ユーザーの意図しない操作が実行される(CSRF攻撃)。
Domain 属性
Cookieが送信されるドメインの範囲を制御。不必要に広いドメイン指定は、サブドメインへのCookie漏洩リスクを高めます。
安全な設定
Set-Cookie: session_id=abc123; Domain=app.example.com危険な設定
Set-Cookie: session_id=abc123; Domain=.example.com (全サブドメインに送信)リスク
攻撃者がサブドメインのXSS脆弱性を悪用して、メインドメインのセッションCookieを窃取できる。
Path 属性
Cookieが送信されるURLパスの範囲を制御。パスを限定することで、不要なページへのCookie送信を防止します。
安全な設定
Set-Cookie: admin_session=xyz; Path=/admin危険な設定
Set-Cookie: admin_session=xyz; Path=/ (全パスに送信)リスク
管理者用セッションCookieが一般ユーザー向けページにも送信され、攻撃面が拡大する。
SameSite 詳細
SameSite属性の値による違い
| 値 | 動作 | 推奨用途 |
|---|---|---|
| Strict | クロスサイトリクエストでは一切Cookieを送信しない。最も厳格だが、外部リンクからのアクセス時にログイン状態が維持されない。 | 認証が重要なアプリ |
| Lax | トップレベルナビゲーション(リンククリック)ではCookieを送信するが、POST/iframe/AJAX等では送信しない。多くのケースで推奨。 | 一般的なWebアプリ(推奨) |
| None | 全てのクロスサイトリクエストでCookieを送信。Secureフラグが必須。サードパーティCookieが必要な場合のみ使用。 | サードパーティ連携(要注意) |
脆弱性の背景
なぜCookie設定が重要なのか
セッションハイジャック
セッションIDを含むCookieが傍受されると、攻撃者は被害者のセッションを乗っ取り、 アカウントに不正アクセスできます。Secureフラグが未設定のCookieはHTTP通信で平文送信されるため、 特に公共Wi-Fiでのリスクが高くなります。HttpOnlyが未設定の場合、XSS攻撃と組み合わせた窃取も可能です。
CSRF(Cross-Site Request Forgery)
SameSite属性が未設定のCookieは、悪意のある外部サイトからのリクエストにも自動的に付与されます。 攻撃者は被害者のブラウザを利用して、認証済みのリクエストを送信させることで、 パスワード変更、送金、データ削除などの操作を実行できます。
Cookie名からのフレームワーク推測
PHPSESSID、JSESSIONID、connect.sid、__Host-next-auth.csrf-token などの Cookie名から使用フレームワークを特定できます。これにより、攻撃者はフレームワーク固有の 脆弱性を狙った攻撃を効率的に実行できるようになります。
実際の被害事例
Cookie設定不備による攻撃事例
GitHubセッションハイジャック脆弱性(2017年)
GitHubのセッションCookieにSecureフラグが適切に設定されていないサブドメインが存在し、HTTP接続を通じてセッションが傍受される可能性がありました。バグバウンティプログラムを通じて報告され、即座に修正されました。
CSRF攻撃によるネットバンキング不正送金
国内の複数の金融機関で、SameSite属性が未設定のセッションCookieを悪用したCSRF攻撃が報告されています。攻撃者が用意した偽サイトにアクセスした被害者の認証済みセッションを利用して、不正な送金リクエストを送信する手法です。
Cookieベースの追跡とプライバシー問題
SameSite=None; Secureが設定されたサードパーティCookieが、ユーザーの同意なくクロスサイト追跡に利用される事例が多発。これを受けて、主要ブラウザはサードパーティCookieの段階的廃止を進めています。Chrome、Firefox、Safariが順次対応を強化しています。
検出メカニズム
Security Scannerの検出方法
Set-Cookieヘッダーの取得
対象URLへのHTTPリクエストのレスポンスから、全てのSet-Cookieヘッダーを取得・解析します。
セキュリティ属性の検査
各CookieのSecure、HttpOnly、SameSite、Domain、Path、Expires属性の設定状況を検証します。
Cookie名の分析
Cookie名からフレームワークの推測リスクを評価。PHPSESSID、JSESSIONID等のデフォルト名の使用を検出します。
セッションCookieの特定
セッション管理に使用されているCookieを特定し、それらに特に厳格な属性設定が適用されているかを確認します。
総合リスクの評価
属性の欠落状況とCookieの種類(セッション/永続/トラッキング)に基づいてリスクスコアを算出します。
修正方法
Cookieの正しい設定方法
推奨されるCookie設定
// Next.js(App Router)- Route Handler でのCookie設定
import { cookies } from 'next/headers';
export async function POST(request: Request) {
const cookieStore = await cookies();
cookieStore.set('session_id', sessionToken, {
httpOnly: true, // JavaScriptからアクセス不可
secure: true, // HTTPS通信でのみ送信
sameSite: 'lax', // クロスサイトPOSTでは送信しない
path: '/', // パスの指定
maxAge: 60 * 60 * 24, // 24時間
});
return Response.json({ success: true });
}Supabase Auth のCookie設定
// Supabase SSR - Cookieオプションの設定
import { createServerClient } from '@supabase/ssr';
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set(name, value, {
...options,
httpOnly: true,
secure: true,
sameSite: 'lax',
});
},
remove(name: string, options: CookieOptions) {
cookieStore.delete({ name, ...options });
},
},
}
);Express.js でのCookie設定
// Express.js + express-session
import session from 'express-session';
app.use(session({
name: 'app_session', // デフォルトの connect.sid を変更
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true,
secure: true, // 本番環境では true
sameSite: 'lax',
maxAge: 24 * 60 * 60 * 1000, // 24時間
domain: 'example.com',
path: '/',
},
}));