2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【セキュリティ】X-Forwarded-For(XFF)とは何か

2
Posted at

はじめに

Webエンジニア、インフラ担当、セキュリティ研究者の間で “よく聞くのに意外と理解されていない” ヘッダーのひとつが X-Forwarded-For(XFF)

結論:XFF は「元のクライアントIPアドレス」を伝えるための HTTP ヘッダー。
リバースプロキシやロードバランサを通過した際に追加される。

しかし、同時に 攻撃者が悪用しやすい脆弱ポイント にもなる。
この記事では、XFF の基本から、攻撃シナリオ、守るためのベストプラクティスまで一気に解説する。


1. X-Forwarded-Forとは?

HTTPヘッダー X-Forwarded-For は、以下のように アクセス元のクライアントIPを残す ために使われる。

X-Forwarded-For: 203.0.113.52

プロキシを何段も通る場合、左から順番に追加されていく:

X-Forwarded-For: 203.0.113.52, 10.0.0.8, 10.0.0.9
  • 一番左:元のクライアント
  • 右側:経由したプロキシ

2. なぜ必要なのか?

Webアプリの前に以下のような構成が置かれている場合:

Client → CDN → Reverse Proxy → App Server

アプリサーバが見えるのは「直前のプロキシのIP」。
これだと:

  • ログが正しく残らない
  • レートリミットが効かない
  • GeoIP 判定が狂う

そこで XFF を使って “本当のクライアントIP” を渡す


3. しかし──攻撃者も簡単に偽装できる

実は、XFF は ユーザが好きな値を入れられる HTTP ヘッダー

攻撃者のリクエスト例:

X-Forwarded-For: 127.0.0.1

アプリが XFF を信用していると……

  • 「ローカルからのアクセス」と誤解
  • 内部専用の管理画面が開く
  • レートリミットが無効化される

などの致命的な脆弱性につながる。


4. 実際の攻撃シナリオ

シナリオ1:内部 IP 信頼バイパス

多くの Web アプリは内部IPを特別扱いする:

if client_ip == "127.0.0.1":
    allow_admin()

攻撃者:

X-Forwarded-For: 127.0.0.1

→ 管理画面に堂々と侵入。

現実に多数の CVE が存在する典型的脆弱性。


シナリオ2:レートリミット bypass

IP で rate-limit する実装:

limit_per_minute per_ip=60

攻撃者は毎回ヘッダーを変えるだけ:

X-Forwarded-For: 1.1.1.1
X-Forwarded-For: 1.1.1.2
X-Forwarded-For: 1.1.1.3

→ 無限リクエスト、爆撃し放題。


シナリオ3:SSRF 制限 bypass

内部アクセス禁止:

deny 127.0.0.0/8

でも判断が XFF ベースだと:

X-Forwarded-For: 127.0.0.2

→ SSRF 保護を突破。


シナリオ4:WAF / CDN 誤判定の利用

Cloudflare などの前に Webサーバが直接 XFF を信用すると:

X-Forwarded-For: 203.0.113.254

→ WAF が「ユーザIPはこれか」と誤解して
ログが汚れ、アクセス制御も崩壊。


5. NGINX / Apache / Cloudflare での正しい扱い

ポイント:信頼できるプロキシだけを信用する

“誰でも送れる XFF を無条件に信じてはダメ!”


NGINX の安全設定

set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
  • set_real_ip_from → 信頼するプロキシだけ(CDN、LBなど)
  • それ以外の XFF は無視される

Apache の例

RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 10.0.0.0/8

Cloudflare + NGINX の組み合わせ

set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
...
real_ip_header CF-Connecting-IP;

Cloudflare では通常 XFF より CF-Connecting-IP を使う。


6. アプリケーション側のベストプラクティス

  • 一番左の XFF を信用しない
  • 信頼できるプロキシから来たヘッダーのみ採用
  • XFF が複数あるときは「最初の不正なIP」を検証
  • クライアントIPに依存した認証・権限判断をしない
    (管理画面を “IPだけで” 認証するのは危険)

7. XFF を使ったペンテスト Tips

ペンテスターは XFF をこう使う:

内部アクセス偽装

X-Forwarded-For: 127.0.0.1

レートリミット bypass

X-Forwarded-For: $(random_ip)

BurpSuite で自動化

Burp Intruder → “Add Header” → XFF

wfuzz

wfuzz -H "X-Forwarded-For: FUZZ" -u http://target/ --hw 0 -w ips.txt

まとめ

テーマ 要点
XFF とは? 元のクライアントIPを伝えるためのヘッダー
役割 ログ、レート制御、GeoIP判定、CDN/プロキシ連携
危険性 攻撃者が簡単に偽造可能
典型攻撃 管理画面バイパス、レートリミット bypass、SSRF bypass
対策 信頼できるプロキシだけを許可し、無条件に信じない
実装方法 NGINX/Apacheの real_ip 系設定を正しく行う

X-Forwarded-For 偽装攻撃 — シーケンス図

攻撃者が
X-Forwarded-For: 127.0.0.1
を付与して、アプリが「内部IPからのアクセス」と誤認して管理画面に入る流れ。

XFF 多段偽装攻撃(プロキシ付き)

攻撃者はプロキシを使い、本来なら:

192.0.2.55(攻撃者のIP)

10.0.0.8(プロキシ)

10.0.0.9(LB)

などが並ぶはず。
しかし 一番左に攻撃者が追加した 127.0.0.1 を置くことで bypass。

レートリミット bypass(XFFローテーション)

攻撃者は XFF を毎回変えて rate-limit を無力化する。

SSRF ガード bypass(XFF ベース判定)

XFF を信用してしまっているアプリが
「内部IPからのアクセスは禁止」 を誤った条件で行っている場合。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?