plan-4ging

2026/03/28

主な構造

HTTP request は大きく4つのパートで構成されている

POST /api/users?page=1&per_page=20 HTTP/1.1        ← RequestLine
Host: api.example.com                               ↑
User-Agent: Mozilla/5.0 (Macintosh; ...)            │
Accept: application/json                            │ Header
Authorization: Bearer eyJhbGci...                   │
Cookie: session_id=abc123; _ga=GAxxxxx              │
Content-Type: application/json                      ↓
                                                   ← 空行(HeaderとBodyの区切り)
{"name": "Test", "email": "test@xxxx.com"}         ← Body

User-Agent

リクエストを送信したクライアント(ブラウザ、OS、アプリ)の識別情報

User-Agent: Mozilla/5.0 (Macintosh; ...)

# curl 経由でのリクエスト
User-Agent: curl/x.x.x

# Bot・クローラー経由でのリクエスト
User-Agent: Googlebot/x.x (+http://www.google.com/bot.html)

読み取れる情報

情報
ブラウザChrome・Firefox・Safari・Edge
ブラウザバージョンChrome/120.0.0.0
OSWindows・macOS・iOS・Android
デバイスPC・スマートフォン・タブレット
bot・クローラーGooglebot・Bingbot など

活用例

  • モバイル / PC でレスポンスを出し分ける
  • bot のアクセスをフィルタリングする
  • ブラウザ互換性のログを取る
  • 不正な自動化ツールのアクセスを検知する(curlpython-requestsなど)

Referer(リファラー)

リクエストの直前にいたページの URL
どこからアクセスしてきたかを示す

# Google 検索から来た場合
Referer: https://www.google.com/search?q=example

# 外部サイトのリンクから来た場合
Referer: https://other-site.com/article/123

# 同一サイト内のページ遷移
Referer: https://example.com/products

# 直接アクセス・ブックマーク・アドレスバー入力の場合
(Referer ヘッダーが存在しない)

活用例

  • アクセス解析・流入元分析
    • どの外部サイト・検索エンジン経由でアクセスしてきたかを記録
  • CSRF 対策の補助的なチェック
    • フォーム送信時にRefererが自ドメインか確認する
    • ただし主要な CSRF 対策は CSRF トークンで行う
  • Hot Link(直リンク)対策
    • Refererが自ドメイン以外からのリクエストをブロックする

Accept

クライアントが受け入れられる形式を伝えるヘッダー群

# 受け入れられるコンテンツタイプ
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

# JSON のみ受け入れる(API クライアント)
Accept: application/json

# 受け入れられる文字エンコーディング
Accept-Encoding: gzip, deflate, br

# 受け入れられる言語
Accept-Language: ja,en-US;q=0.9,en;q=0.8

# 受け入れられる文字セット
Accept-Charset: utf-8, iso-8859-1;q=0.5

活用例

  • Accept-Language:ユーザーのブラウザ設定言語を取得してデフォルト表示言語を決定する
  • Accept-Encodinggzip対応なら圧縮レスポンスを返してデータ量を削減する
  • Accept:コンテンツネゴシエーション(同一エンドポイントで HTML / JSON を出し分ける)

Host/Origin/X-Forwarded-For

# リクエスト先のホスト名
Host: api.example.com

# リクエストの発生元オリジン(CORS・クロスオリジンリクエストで重要)
Origin: https://app.example.com

# ロードバランサー・プロキシを経由したクライアント IP
X-Forwarded-For: { IP }, { IP }, { IP }
# 通常左端が本来のクライアント IP、右に進むほど経由したプロキシ IP

# X-Forwarded-For の後継(RFC 7239)
Forwarded: for=xxx.x.xxx.xx;proto=https;host=example.com

Content-Type/Content-Length

# リクエストボディの形式
Content-Type: application/json
Content-Type: application/x-www-form-urlencoded
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
Content-Type: text/plain

# リクエストボディの byte サイズ
Content-Length: 1234

その他

Header概要用途
Cache-Controlキャッシュの制御指示no-cache でキャッシュをスキップしているか判断
Connection接続の維持方法keep-alive/close
X-Requested-WithAjaxRequestの識別XMLHttpRequestAjaxか判断
X-Request-IDリクエストの一意識別子分散トレーシング・ログの追跡
Sec-Fetch-Siteリクエストの発生元種別same-origin/cross-site / none
Sec-Fetch-Modeリクエストのモードnavigate/cors/no-cors
Sec-Fetch-Destリクエストの宛先document/image/script など

IP アドレス・クライアント情報

IP アドレス

GeoIP(ジオアイピー)サービスを使用することで、IPアドレスから地域を特定できる

├ 接続元の国・地域(GeoIP)
├ ISP・組織名(WHOIS)
├ データセンターIPかどうか(VPN・プロキシ・bot検知などに使う)
└ 同一IPからの連続アクセス(Rate Limit・ブルートフォース検知)

セミコロン(;)区切りで複数の Cookie が送られてくる
名前=値の形式

# リクエストヘッダーに含まれる Cookie
Cookie: session_id=abc123xyz; _ga=GAxxxxxxx; lang=ja
Cookie 名(例)用途
session_id / _sessionセッション ID
_ga / _gidGoogle Analytics のトラッキング
lang / locale言語設定
csrf_tokenCSRF トークン
remember_me_tokenログイン状態の維持

読み取れる情報

  • ログイン中のユーザー ID
  • 一時的なフォーム入力データ
  • フラッシュメッセージ(1回のみ表示する通知)
  • CSRF トークン

認証・認可情報

Authorization Header

# Basic 認証(Base64 エンコードされた username:password)
Authorization: Basic dGVzdDpwYXNzd29yZA==

# Digest 認証(Basic 認証のハッシュ版)
Authorization: Digest username="user", realm="example.com", ...

# Bearer トークン(JWT・OAuth アクセストークン)
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# API キー認証
Authorization: ApiKey sk-xxxxxxxxxxxxxxxxxxxx

JWT(Bearer トークン)

JWT はヘッダー.ペイロード.署名の3部構成
ペイロード部分をBase64デコードすると以下のような情報が取得できる

{
  "sub": "user_123",                 # ユーザー ID(Subject)
  "email": "test@xxxxx.com",       # メールアドレス
  "role": "admin",                   # ロール・権限
  "iss": "https://auth.example.com", # 発行者(Issuer)
  "aud": "https://api.example.com",  # 受信者(Audience)
  "exp": 1700000000,                 # 有効期限(Unix タイムスタンプ)
  "iat": 1699996400,                 # 発行日時(Issued At)
  "jti": "uuid-xxx"                  # JWT ID(リプレイ攻撃対策)
}

Request Body / Query Parameter

Request Body

application/jsonなど

{
  "user": {
    "name": "Test User",
    "email": "test@xxxxx.com",
    "age": 30
  }
}

Query Parameter

GET /api/users?page=2&per_page=20&sort=created_at&order=desc&q=test

活用例

不正アクセス検知・防御

ブルートフォース攻撃の検知

同一 IP からのログイン失敗回数を Redis でカウントする

検知条件の例:
├ 同一IPから 5分以内に 10回以上ログイン失敗
├ 同一 User-Agent から短時間で大量リクエスト
├ X-Forwarded-For が異常な値(改ざんの疑い)
└ Referer が空なのに POST リクエスト(botの疑い)

対応:
├ 一定時間IPをブロック(fail2ban、アプリ層での制御)
├ CAPTCHA を表示
└ アラートを通知(Slack、PagerDutyなど)

bot・スクレイピング検知

以下の組み合わせで判断する(どれか1つでは判断しない

User-Agent
├ curl・python-requests・Scrapy などのライブラリ名が含まれる
├ 既知のbot
└ 空または極端に短い

リクエストパターン
├ 人間には不可能な速度(1秒以内に連続リクエスト)
├ 特定のパスへの集中アクセス
└ Accept-Language・Accept-Encoding が省略されている

IP
├ データセンター IP(AWS、GCP、Azure などのレンジ)
├ Tor 出口ノード
└ 既知の悪意ある IP(AbuseIPDB 等で確認)

アクセスログ・アナリティクス

リクエストごとに以下などを記録しておくと障害調査・分析時に役立つ

├ タイムスタンプ
├ リクエストID(X-Request-ID)
├ HTTP メソッド・パス・クエリパラメータ
├ ステータスコード
├ レスポンスタイム
├ クライアント IP(X-Forwarded-For の最初の信頼できる IP)
├ User-Agent
├ ユーザーID(認証済みの場合)
├ Referer
├ Content-Length(レスポンスサイズ)
└ X-Forwarded-Proto(HTTP/HTTPS の判別)

フォーマット例(JSON)
{
  "timestamp":    "2024-01-15T10:30:00.123Z",
  "request_id":  "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "method":      "POST",
  "path":        "/api/orders",
  "status":      201,
  "duration_ms": 234,
  "ip":          "xxx.x.xxx.xx",
  "user_id":     "user_123",
  "user_agent":  "Mozilla/5.0 ...",
  "referer":     "https://example.com/cart"
}

パーソナライゼーション

リクエスト情報を組み合わせてユーザーエクスペリエンスを最適化する

Accept-Language → ユーザーの言語設定に合わせてデフォルト言語を決定
User-Agent      → モバイル / PC でレイアウト・コンテンツを出し分け
IP の地域情報     → 地域に合わせた通貨・配送情報・サービスを表示
Cookie          → A/B テストのグループ分け情報を保持
Referer         → 流入元に合わせたランディングページの内容を変更

注意点

ログに記録してはいけない情報

下記などはログに残すべきではない

✗ パスワード(平文・ハッシュ問わず)
✗ クレジットカード番号(PAN)・CVV
✗ JWT トークン・APIキー・シークレット
✗ Cookie の値(セッションID を含む)
✗ Authorization ヘッダーの値(フルの文字列)

【マスキング例】
Authorization: Bearer eyJhbGci...  → Bearer ey***(先頭数文字のみ)
Cookie: session_id=abc123          → session_id=***(値をマスク)

個人情報・プライバシー考慮

IPアドレスやUser-Agent/Refererなど、個人情報となるため扱いに十分に気を付ける(法律遵守、長期保存しないなど)

信頼してはいけない情報

クライアントから送られる情報は基本的に信頼しない

信頼できない情報の例:
├ User-Agent         → 簡単に偽装できる
├ Referer            → 省略・偽装が可能
├ X-Forwarded-For    → クライアントが任意の値を設定できる
├ Content-Type       → 実際のコンテンツと一致する保証がない
└ リクエストボディの値  → バリデーション必須

対策の原則

  • サーバー側で必ずバリデーションを行う
  • クライアントの情報を鵜呑みにしない
  • IPアドレスの信頼性は使用しているプロキシ構成に依存する
    • 信頼できるプロキシのIPを明示的に設定して管理する

リクエスト情報の取得先

情報取得元注意点
クライアントIPX-Forwarded-ForREMOTE_ADDRプロキシ経由の場合は要注意
ブラウザ・OSUser-Agent偽装可能
流入元 URLReferer省略・偽装される場合がある、ブラウザ起因で送られない可能性がある
言語設定Accept-Languageブラウザ設定であってユーザーの言語とは限らない
認証情報Authorization
セッションCookie署名・暗号化して使う
フォームデータRequestBodyバリデーション必須
検索条件QueryParameterログ・履歴に残ることを意識する
オリジンOriginCORS の判断に使う
Ajax判定X-Requested-With偽装可能なため補助的に使う
トレーシングX-Request-IDログの追跡・障害調査に活用

参考