0
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?

【セキュリティ】IDOR(不安全な直接オブジェクト参照)

Last updated at Posted at 2025-10-02

はじめに

IDOR(Insecure Direct Object Reference)は、ユーザが指定する識別子(ID、ファイル名、トークンなど)を通じて、本来アクセス権のない別ユーザのリソースに到達できてしまう脆弱性です。

原因は単純で、サーバ側で 「そのリクエストが本当にそのユーザに許可されているか」 を検証していないことにあります。この記事では、発見方法(特に Encoded / Hashed ID の扱い方)、テスト手順、実務的な対策、報告テンプレまでを実践的にまとめます。


なぜ危険か

  • 個人情報や機密ファイルの漏洩につながる。
  • 認可バイパスを足がかりに、さらなる権限昇格や改ざんに発展する。
  • API や Web インターフェースの設計ミスがあれば、簡単なリクエスト改ざんで侵害可能。

発生する典型的な場面

  • URL のクエリパラメータ:GET /invoice?id=1001
  • POST ボディ/JSON:{"fileId":"abc123"}
  • クッキー、Referer、Hidden フィールド、JWT とは別の補助IDなど
  • これらが 所有者検証なし に処理されると発生する

Encoded IDs(エンコードされたID)の扱い方

特性

  • 一般的に Base64 が多い(A–Z a–z 0–9 + /= パディング)。
  • Base64 は 暗号化ではなくエンコード。誰でもデコードできる。

テスト手順(実践)

  1. 対象パラメータが Base64 風か確認(文字セット・= の有無をチェック)。
  2. デコード(例:base64decode.org、ローカルの base64 コマンド)して中身を確認。
  3. ID 部分を別ユーザの値に書き換え(あるいは簡単な連番に変更)。
  4. 再エンコードしてリクエストを再送。レスポンスが変われば脆弱性の可能性あり。

注意点

  • Base64 の中に JSON や複合データが入っている場合がある(構造を壊さないよう注意)。
  • サニタイズや署名(HMAC)が付いていると単純に編集できない場合もある。

Hashed IDs(ハッシュ化ID)の扱い方

特性

  • ハッシュ(MD5/SHA1 等)は一方向。理論上は可逆ではないが、実務では辞書/レインボーテーブルや総当たりで逆引きされることがある。
  • 小さな連番 ID をハッシュしているだけだと総当たりで簡単に特定される。

テスト手順(実践)

  1. 発見したハッシュ文字列の形式(長さ)からハッシュ方式を推定
  2. CrackStation 等のオンラインサービスで逆引きを試す
  3. 連番 ID の可能性があるなら、自分で hash(candidate) を生成して照合(スクリプトや hashcat を利用)

注意点

  • ソルトや HMAC が使われている場合は成功しにくいが、所有者チェックをサボっているケースがまだある

実務的な探索フロー(チェックリスト)

  1. 入力を洗い出す:URL、POST、Cookie、Hidden、JSON、API ヘッダ等
  2. 識別子の種類を判定:整数連番/UUID/Base64/ハッシュ
  3. 改変可能性を試す:連番増減、Base64 decode→edit→encode、ハッシュ逆引き
  4. レスポンス確認:HTTP ステータス、コンテンツ差異、ダウンロード可否、漏洩情報の有無
  5. ログを残す:成功時はリクエスト・レスポンスのスクショ/ペイロード保存(再現性のある証跡)
  6. 安全に報告:影響範囲、手順、再現用コマンドを開発チームに提出

使用すると便利なツール

  • Burp Suite(Proxy、Intruder、Repeater)
  • OWASP ZAP
  • CLI:curl, httpie
  • 文字列処理:base64(Linux/macOS)、openssl、Python スクリプト
  • ハッシュ解析:CrackStation、hashcat、John the Ripper

サーバ側での防御(実装上の必須事項)

  1. 必ずサーバ側で認可(Authorization)を行う
    • resource.owner_id == current_user.id を必ずチェック
    • 「ログインしているか」だけでは不十分
  2. 予測困難な識別子を使う(補助)
    • 単なる対策であり、認可チェックの代替ではない。UUID や長いランダムトークンを使う
  3. 可能なら ID を送らせない設計
    • 例:GET /me/files のように現在ユーザのコンテキストで返す
  4. ハッシュを使う場合でも HMAC やソルトを併用する
    • ただし所有者確認は必須
  5. 監査ログと異常検知
    • 短時間に大量の別 ID へアクセスがあればアラートを上げる
  6. 最小権限・ロールベース/属性ベース認可を導入する

開発者向けコード例(簡潔に)

Python / Flask(擬似コード)

@app.route('/invoice')
def invoice():
    invoice_id = request.args.get('id')
    inv = Invoice.query.filter_by(id=invoice_id).first()
    if not inv:
        abort(404)
    if inv.owner_id != current_user.id:
        abort(403)
    return send_file(inv.path)

レポート(脆弱性報告)テンプレ

  • タイトル: IDOR — /file?id=<編集値> による未承認のファイルアクセス
  • 環境: production / staging(該当を明記)
  • 再現手順:
    1. ログインユーザ A で GET /file?id=eyJpZCI6IjEwMDEifQ== を取得(Base64 表示)
    2. デコードして {"id":"1002"} に編集、再エンコードしてリクエスト
    3. ユーザ B のファイルがダウンロードできる
  • 期待される挙動: サーバは file.owner_id == current_user.id を検証し、権限がなければ 403 Forbidden を返すべき
  • 影響度: 機密ファイル漏洩の可能性
  • 推奨対応: サーバ側での所有者確認、監査ログ、短期的にIDの再設計(UUID化)を実施

まとめ

  • IDOR の本質は 「認可チェックの欠如」 にある。エンコードやハッシュの有無は実務上の妨げにはならない(工夫次第で解析可能)
  • ペネトレーション/セキュリティテストでは 入力を洗い出して改ざんしてみる こと、開発側は 受け取った識別子の所有者確認を必ず行う ことが最も重要
  • 実装・設計の両面で対策(API 設計、認可ロジック、監査)を組み合わせることでリスクを低減できる

0
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
0
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?