【CTF実践編|第2話/全10話】IDORで他人の情報を覗く|権限昇格チェーン

⚡ CTF実践編|第2話/全10話

IDORで他人の情報を覗く|権限昇格チェーン

URLやAPIに渡すID番号を1つ変えるだけで、本来は見えないはずの他人の情報が見えてしまう「IDOR」を体験します。一般社員のIDから手がかりを掴み、管理者のIDへとたどり着く2段階のチェーンに挑戦しましょう。

🔢 IDOR 📇 オブジェクト参照 🔗 権限昇格チェーン ⭐ 難易度:★★★☆☆
01

💭 前回の振り返り|権限はクライアントだけで守れない

第1話の教訓を、もう一段深く掘る

🔗

第1話では「Cookie書き換え」でしたが…

第1話では、Cookieのrole値を書き換えるだけで管理者ビューが開いてしまう脆弱性を扱いました。今回のIDORも根っこは同じです。「クライアントが指定した値を、サーバー側が十分に検証せずそのまま信用してしまう」という設計ミスが、形を変えて何度も登場します。

📌

この話の前提知識

今回は前作の権限管理の基礎を前提にします。不安な場合は先に読み返しておきましょう。

今回はCookieではなく「IDの番号」が攻撃の起点になります。あなた自身のIDから始めて、ID番号を変えていくことで他人の情報に到達し、さらにその情報から次のIDを発見するという、2段階の「チェーン」を体験します。CTF実践編のテーマである「複数の技術を繋ぐ」を、今回は同じ1つの技術(IDOR)を2回繰り返して繋ぐ、というシンプルな形で体感していただきます。

02

🔢 IDORとは何か|オブジェクト参照を直接指定する危険

Insecure Direct Object Reference(安全でない直接オブジェクト参照)

IDOR(Insecure Direct Object Reference)とは、ユーザーが指定したID(番号やファイル名など)に対応するデータを、サーバーが「このIDを要求した人に見る権限があるか」を確認せずそのまま返してしまう脆弱性です。/profile?user_id=1001のようなURLで、10011002に変えるだけで他人のプロフィールが見られてしまう、というのが典型例です。

あなた GET /profile?user_id=1001 (自分のID) サーバー:権限チェックなし 「誰が要求したか」を見ていない 1001のデータ GET /profile?user_id=8842 (他人のID!) 同じく権限チェックなし ⚠ IDが違うだけで素通り 8842のデータ (本来は見えないはず) IDOR:IDを変えるだけで「あなたが見てよいか」の判定をすり抜けてしまう
⚠️

OWASP Top 10にも含まれる定番の脆弱性

IDORはOWASPが分類する「Broken Access Control(アクセス制御の不備)」という大きなカテゴリの代表例です。実装の見た目はシンプルですが、発見しやすく被害も大きいため、バグバウンティ(脆弱性報奨金制度)でも頻繁に報告される脆弱性の1つです。

たとえば「請求書PDFをダウンロードするURLにinvoice_id=1001という番号がそのまま使われていて、番号を1つずつ変えるだけで他人の請求書(氏名・住所・金額などの個人情報を含む)が次々にダウンロードできてしまった」というパターンは、実際のバグバウンティ報告でも繰り返し見られる典型例です。請求書・予約情報・チャット履歴など、「自分のものだけ見えるはず」のデータほど、IDORの被害が深刻になりやすい領域だと言えます。

03

📇 IDORが生まれやすいID設計

IDの「形」によって攻撃のしやすさが変わる

すべてのID設計が同じように危険というわけではありません。ID自体が「予測しやすいか」によって、IDORの悪用しやすさが大きく変わります。

ID設計IDORでの悪用しやすさ
連番の整数1001, 1002, 1003...非常に高い。+1ずつ試すだけで総当たりできる
推測可能な規則user_2024_001高い。規則さえ分かれば候補を絞れる
ランダムなUUIDa8f3c1e2-...低い(ただし他の手段でUUIDが漏洩すれば同じく危険)
署名付きトークンJWT等に埋め込み、改ざん検知最も低い(第3話で詳しく扱います)
💡

「推測しにくいID」は対策の1つだが、それだけでは不十分

UUIDのようなランダムなIDにすれば、総当たりでの発見は難しくなります。しかし、それは「見つかりにくくする」だけであり、「権限チェックをしない」という根本的な設計ミスを直してはいません。IDが漏洩する経路(ログ・共有リンク・エラーメッセージなど)が1つでもあれば、結局同じ問題が起こります。本当の対策は、サーバー側で「このIDのデータを、今リクエストしている人が見てよいか」を毎回検証することです。セキュリティの世界では、このような「見つかりにくくするだけの対策」をSecurity through obscurity(隠すことによる安全)と呼び、単独では信頼できない対策の代表例として知られています。

04

🕵️ 実践チャレンジ:社内ポータルでIDを覗き見る

2段階のIDORチェーンでadminのメモに到達する

架空の社内ポータル「やさい商事プロフィール検索」では、user_idを指定すると誰でもプロフィールを閲覧できてしまいます(権限チェックがありません)。あなたのIDは1001です。他のIDを試して、手がかりを探してください。

🎯

チャレンジの手順

① 下のポータルでID1001(自分)を表示して状況を確認 → ② 他のID(1000番台)を何個か試して同僚のプロフィールを探す → ③ 見つけた同僚のメモに書かれている管理者のadmin_idを確認 → ④ ステージ1にその情報を入力 → ⑤ 解放されたステージ2のヒントに従い、admin_idでプロフィールを表示してメモから最終フラグを入手。

🧩 実践チャレンジ:2つのステージを繋いでフラグを掴め

ステージ1をクリアすると、ステージ2が解放されます。両方クリアした時点でスコアが確定します。

📊 ステージ進捗: 0/2|挑戦回数: 0回

1ステージ1:次の標的を発見する

同僚のプロフィールに書かれていた管理者のIDを、ADMIN-番号の形式で入力してください(例:ADMIN-1234)。

05

🔗 なぜIDORは今も多発するのか

「動くコード」が「安全なコード」とは限らない

IDORが今も頻発する理由の1つは、権限チェックを入れなくても機能テストでは正常に動いてしまうことです。開発者自身のテストアカウントでログインして確認する限り、自分のデータしか触らないため、権限チェック漏れに気づきにくいのです。バグが見つかるのは、悪意のある第三者(またはCTFプレイヤー)がIDを書き換えて初めて、というケースが少なくありません。

🛡️

防御側の対策:オブジェクトレベルの権限チェック

正しい実装では、データを返す直前に必ず「このリクエストを送ってきたユーザー(ログイン情報から判定)が、要求されたIDのデータを見る権限を持っているか」をサーバー側で確認します。これを徹底するだけでIDORはほぼ防げますが、API数が多いシステムでは1つでも確認漏れがあれば突破口になるため、地味ながら見落としやすい対策です。

今回のチャレンジは、実は2種類の権限昇格を1つのチェーンに組み込んでいます。ID1037の同僚プロフィールを見る行為は「同じ立場の他人のデータを覗く」水平権限昇格(Horizontal Privilege Escalation)です。一方、そこで得た手がかりからID8842の管理者プロフィールに到達する行為は「より高い権限のデータに到達する」垂直権限昇格(Vertical Privilege Escalation)にあたります。実際の攻撃チェーンでも、まず水平方向に複数のアカウントを覗いて手がかりを集め、最後に垂直方向へ一気に踏み込む、という流れがよく見られます。

次回は、今回見つけた「管理者かどうか」を判定する仕組みそのものを狙います。Cookieの値でもIDの番号でもなく、JWT(JSON Web Token)という署名付きのトークンを偽造し、サーバーに「自分は管理者だ」と信じさせる技術に挑戦します。

06

📝 まとめ+FAQ+次回予告

IDの番号1つが、権限昇格の入口になる

第2話では、IDの番号を変えるだけで他人の情報に到達できてしまうIDORを体験しました。1段階のIDORだけでなく、見つけた情報から次のIDを発見し、さらに深い情報へと進む「チェーン」の感覚をつかんでいただけたなら成功です。

✅ 今回のまとめチェック

・IDOR=サーバーが「このIDを見てよい人か」を確認せずデータを返してしまう脆弱性
・連番IDは総当たりしやすく、UUIDや署名付きトークンはより安全
・IDORは1段階で終わらず、発見した情報から次のIDに繋がる「チェーン」になることがある
・対策はID設計の工夫だけでなく、サーバー側でのオブジェクトレベルの権限チェックが本質
・ヒントを使うと-15pt、両ステージ解決でスコア確定という採点ルールは前回と同じ

Q. 実際のWebサービスでIDを総当たりして試したらどうなりますか?

許可されていない実在のサービスに対してこれを行うと、不正アクセス禁止法等の対象になる可能性があります。本シリーズのチャレンジはすべて自作のダミー環境です。実際に試したい場合は、CTFや許可されたバグバウンティプログラムの対象内でのみ行ってください。

Q. IDORとCSRF(クロスサイトリクエストフォージェリ)は同じものですか?

異なります。IDORは「権限チェックの欠落」が原因で、自分のリクエストでも他人のデータに到達できてしまう問題です。CSRFは「別サイトから本人になりすましてリクエストを送らせる」問題です。両者は組み合わさることもありますが、原因と対策は別物です。

Q. UUIDを使えばIDORは完全に防げますか?

総当たりは防げますが、それだけでは不十分です。UUIDがログ・URL共有・エラーメッセージなどから漏洩すれば、結局そのIDで他人のデータにアクセスできてしまいます。本質的な対策は、サーバー側の権限チェックを徹底することです。

Q. このチャレンジのID番号は本当に何でも試せるのですか?

はい。1000番台のID(自分以外)を入力すると、該当する番号にはダミーの同僚プロフィールか「該当する社員情報はありません」という表示が返ります。実際のIDOR調査の「総当たりで探す」感覚を体験できるよう設計しています。

次回・第3話

JWTを偽造する|alg:noneと弱い署名鍵

JWT(JSON Web Token)の構造をデコードし、署名の弱点を見つけて「自分は管理者だ」と主張するトークンを偽造する技術に挑戦します。

📚 参考情報

  • OWASP Top 10「A01: Broken Access Control」
  • OWASP「Insecure Direct Object Reference Prevention Cheat Sheet」

コメント