utsuroi csrf labs Lab 04 / 5 — Practitioner
04

Referer 検証の回避 — 部分一致の罠

Referer validation bypass via substring matching

うつろい EC は CSRF 対策として Referer 検証を採用(Token は使っていない)。サーバ側のコード:

// PHP
$referer = $_SERVER['HTTP_REFERER'] ?? '';
if (strpos($referer, 'shop.utsuroi.example.com') === false) {
    abort(403);
}
// ↑ Referer 文字列に 'shop.utsuroi.example.com' が含まれていれば OK

これは古典的な実装ミス。「含まれているか」だけを見ているので、攻撃者が自分のドメインに shop.utsuroi.example.com という文字列を含ませれば素通りしてしまう。

Referer 検証を回避する攻撃者ドメインを下のリストから選んで、CSRF を成立させてください。

shop.utsuroi.example.com / mypage
送られる Referer ヘッダ
(まだ攻撃を実行していません)
サーバの判定
(待機中)
ヒント 1 — strpos の意味

PHP の strpos($haystack, $needle) は「$needle$haystackどこかに含まれているか」を見ます。先頭一致でも完全一致でもなく、部分一致。これを利用して...

正解(ネタバレ)

2つの回避ベクトルがあります:

  • https://shop.utsuroi.example.com.evil.com/promo — サブドメイン汚染
  • https://attacker.com/?x=shop.utsuroi.example.com — クエリ文字列に偽装

どちらも文字列としては shop.utsuroi.example.com を含むので、strpos ベースのチェックを通過。「ホスト部の完全一致」を見るのが正解です。