utsuroi access control labs Lab 04 / 5 — Practitioner
04

UUID 経路の認可不備 — 「予測不可能」だけでは守れない

UUIDs do not provide access control

Lab 01 の IDOR を受けて、うつろい EC は注文 ID を連番から UUID に変更した。/orders/12345 ではなく /orders/a3f8c9...。これで「他人の ID は推測できない」ので安全、と開発者は考えた。

しかし、注文に紐付くレビュー API GET /api/products/{id}/reviews のレスポンスに、レビュー投稿者の order_uuid が含まれている。攻撃者はこの API から他人の UUID を入手し、注文詳細 API で使える。サーバ側の所有者チェックが無いため、UUID を知っているだけで他人の注文が見える。

① 商品レビュー API から他人の order_uuid を取得
② その UUID を使って注文詳細 API を呼び、他人の注文情報を取得

① 商品レビュー API を呼び出し

② 取得した UUID で注文詳細 API を呼び出し

レスポンスから他人の order_uuid をコピーして下に入れる。

脆弱な実装パターン
// API 1: レビュー一覧 — UUID をうっかり露出
GET /api/products/nagi/reviews
=> [
  { "user": "miharu_t", "order_uuid": "a3f8c9d2-...", "comment": "..." }
  //  ↑ 他人の order_uuid をレスポンスに含めてしまっている
]

// API 2: 注文詳細 — UUID 一致だけで返す(認可なし)
GET /api/orders/a3f8c9d2-...
=> { "user": "miharu_t", "address": "...", "items": [...] }
//   ↑ 「current_user が所有者か」のチェックなし

UUID 自体は推測できないが、別の API から漏れると簡単に手に入る。これは認可不備の根本原因が「ID の見えづらさ」ではなくサーバ側のチェック欠落であることを示す典型例。

正解(ネタバレ)

① レビュー API を呼ぶと、各レビューに order_uuid が含まれている。② その UUID をコピーして注文詳細 API に渡せば、他人の注文情報が取得できる。

このパターンは実際の事案でも頻発します。「主 API では UUID をパスに使うが、サブ API のレスポンスでは内部 ID や UUID をうっかり露出してしまう」というアンチパターン。設計時にどのフィールドをレスポンスに含めるかを毎回明示的にレビューする必要があります。