メインコンテンツへスキップ
SDETRole
SDETRole

用語集 · セキュリティ

IDOR(安全でない直接オブジェクト参照)

英語: IDOR

別名: 安全でない直接オブジェクト参照, BOLA, オブジェクトレベル認可の不備, Insecure Direct Object Reference

定義

Insecure Direct Object Reference の略で、リクエスト内の ID を書き換えるだけで他のユーザーのデータを閲覧・変更できてしまうアクセス制御の欠陥です。

IDOR(Insecure Direct Object Reference、安全でない直接オブジェクト参照)とは、アプリケーションが /api/orders/1043 のようなリクエスト内の識別子を使ってレコードを取得するものの、ログイン中のユーザーがそのレコードにアクセスしてよいかを確認していない脆弱性です。ID を 1044 に変えると、他人の注文が取得できてしまいます。OWASP Top 10 2021 では A01 アクセス制御の不備に該当し、OWASP API Security Top 10 では同じ問題を Broken Object Level Authorization(BOLA)と呼んでいます。

具体例

Alice はログインして自分の注文を見ています。

GET /api/orders/1043
Authorization: Bearer <alice-token>

彼女は番号を変えます。

GET /api/orders/1044
Authorization: Bearer <alice-token>

レスポンスが 200 で Bob の住所や商品が返ってきたら、そのエンドポイントはユーザーを認証してはいるものの、特定のオブジェクトへのアクセスを認可していません。推測しにくい UUID を使えば推測は難しくなりますが、欠陥そのものは直りません。ID は URL、ログ、共有リンクから漏れるからです。

テスターが確認すること

それぞれ自分のデータを持つテストユーザーを 2 人作り、すべてのエンドポイントとメソッド(読み取り、更新、削除、そして /users/{id}/invoices のようなネストしたルート)で、ユーザー A の認証情報を使ってユーザー B のオブジェクトにアクセスします。これは簡単に自動化できます。Playwright の例です。

import { test, expect, request } from '@playwright/test';

test("Alice cannot read Bob's order", async () => {
  const alice = await request.newContext({
    baseURL: process.env.API_URL,
    extraHTTPHeaders: { Authorization: `Bearer ${process.env.ALICE_TOKEN}` },
  });
  const res = await alice.get(`/api/orders/${process.env.BOB_ORDER_ID}`);
  expect([403, 404]).toContain(res.status());
  await alice.dispose();
});

403 と 404 はどちらも許容されます。多くの API は、レコードが存在することすら明かさないよう 404 を返します。あわせて次の点も確認します。

  • パスだけでなく、リクエストボディやクエリ文字列に含まれる ID。
  • 書き込み操作。IDOR があると、ユーザーがデータを変更・削除できてしまいます。
  • ID のリストを受け付ける一括処理やエクスポートのエンドポイント。
  • マルチテナントシステムにおけるテナント間の境界。

なぜ見逃されるのか

機能テストは通常 1 人のユーザーでログインし、そのユーザー自身のデータを使うため、認可チェックが一度も実行されません。IDOR は、すべてのエンドポイントについて「この ID が他人のものだったらどうなるか?」と問いかけることで見つかります。これらのテストは、テストする権限を与えられたシステムに対してのみ実行してください。

キーワードを入力すると SDETRole 全体を検索できます。

Pagefind による全文検索 · ブラウザ内で動作します 検索ページを開く →