※本記事にはプロモーションが含まれています。
CSRF対策として「SameSite属性を設定しているから安全」と考えていませんか。
確かに SameSite=Strict は強力な防御ですが、実装によっては回避されるケースがあります。
この記事では、Web Security Academyのラボ「SameSite Strict bypass via client-side redirect」をもとに、
- なぜSameSiteがあってもCSRFが成立するのか
- WordPressではどのような実装ミスが起こり得るのか
を解説します。
CSRFの基本については以下の記事で解説しています。
SameSite Strict bypass via client-side redirectラボ概要
このラボでは、メールアドレス変更機能にCSRF脆弱性があります。
特徴は以下の通りです。
- セッションCookieに
SameSite=Strictが設定されている - 一見するとCSRFは不可能に見える
- しかし、クライアント側リダイレクトを利用することで攻撃が成立する
クライアント側リダイレクトを利用した攻撃の流れ
今回の攻撃は、単純なCSRFではありません。
以下のような流れで成立します。
- 被害者が攻撃ページにアクセス
- 正規サイトの確認ページに遷移させる
- ページ内のJavaScriptがリダイレクトを実行
- 同一サイト内リクエストとして扱われる
- Cookie付きでメール変更リクエストが送信される
※CSRFはトークンの実装不備によっても成立します。
▶ WordPressで考えるCSRF対策の落とし穴|トークン未送信で突破されるケース
SameSiteが効かない理由
SameSite=Strictは、クロスサイトリクエストにCookieを付与しません。
しかし今回のケースでは、
- 最初のアクセス → クロスサイト
- その後のリダイレクト → 同一サイト
と扱われます。
つまりブラウザは、「これはサイト内の通常遷移だ」と判断し、Cookieを付与してしまいます。
攻撃者はどこに注目するのか
攻撃者が見ているのはここです。
- URLパラメータがそのままJavaScriptで使われている
- その値がリダイレクト先として使われている
今回のコードは以下のような構造でした。
const postId = url.searchParams.get("postId");
window.location = blogPath + '/' + postId;この実装には問題があります。
- 入力値の検証がない
- URLとして扱っている
つまり攻撃者は、
postId = 1/../../my-account/change-email?email=attacker@evil.com&submit=1のような値を渡すことで、意図しないページにリダイレクトさせることができます。
WordPressで起こり得る実装ミス
WordPressでも似たような問題は普通に起きます。
例1:リダイレクト処理の実装ミス
$redirect = $_GET['redirect'];
wp_redirect('/post/' . $redirect);このようなコードがあると、
../を使ったパス操作- 任意ページへの遷移
が可能になります。
例2:JavaScriptでの遷移制御
const next = new URL(location).searchParams.get("next");
location = "/mypage/" + next;このような実装も同様に危険です。
例3:コメント後の遷移処理
今回のラボと同じく、
- コメント投稿後
- フォーム送信後
- 完了ページ表示後
などにJSで遷移させているケースは特に注意が必要です。
なぜ気づきにくいのか
この問題はかなり見落とされやすいです。
理由は以下の通りです。
- SameSiteを設定していることで安心してしまう
- CSRF対策はサーバー側だけ見がち
- クライアント側の挙動を考慮していない
こうしたリダイレクトやURL処理の問題は、サーバー側の設定だけでは防げないケースもあります。
最低限のWAFやセキュリティ対策を備えた環境での運用が重要です。
エックスサーバー
▶ エックスサーバー公式サイトはこちら
SameSiteだけに依存しないCSRF対策
対策はシンプルですが重要です。
入力値をそのままURLに使わない
- 数値なら数値として扱う
- パスならホワイトリストで制御する
リダイレクト先を固定する
wp_redirect('/post/');のように、ユーザー入力を使わない設計にする。
CSRFトークンを正しく実装する
SameSiteだけに依存せず、
- トークン検証
- セッションとの紐付け
を行う。
クライアント側の処理も監査対象にする
- JavaScriptでのURL操作
- location変更
- パラメータ利用
これらも含めて確認する。
セキュリティ診断でのチェックポイント
実務で見るならここをチェックします。
- URLパラメータがそのままリダイレクトに使われていないか
- JavaScriptでURLを組み立てていないか
../を使ったパス操作が可能でないか- SameSiteに依存した設計になっていないか
まとめ│SameSiteでも防げないCSRFから学ぶべきこと
SameSite=Strictは強力な対策ですが、万能ではありません。
特に、
- クライアント側リダイレクト
- ユーザー入力のURL利用
が組み合わさると、簡単に回避されることがあります。
CSRF対策は単体ではなく、設計全体で考える必要があります。
