mcpField
I
idor-testing

idor-testing

github.com/sickn33セキュリティ48.7k152 回インストール今日更新
リポジトリ

idor-testing について

idor-testingは、Webアプリケーションの不安全な直接オブジェクト参照(IDOR)を特定・評価するセキュリティテスト用スキルです。データベースオブジェクトやファイルを対象とする許可済みのテスト方法に加え、証拠の記録と修正指針を示します。

主な機能

  1. 01オブジェクトとファイル参照の調査
  2. 02パラメーターとリクエストの改変テスト
  3. 03ユーザー間アクセスの評価
  4. 04エンドポイントと影響の記録
  5. 05修正指針の提示

活用シーン

  1. 01許可済み評価でアクセス制御を確認
  2. 022つのテストアカウントで参照を検証
  3. 03IDOR調査レポートを作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill idor-testing

インストール後、Claude Code で/idor-testingを入力して読み込まれたか確認します。

詳細

⚠️ 許可された使用のみ このスキルは、教育目的または許可されたセキュリティ評価のみを対象としています。 このツールを使用する前に、システム所有者から明示的な書面による許可を得る必要があります。 このツールの悪用は違法であり、厳しく禁止されています。

必須の確認ゲート ターゲットに対してプローブ、悪用、変更、永続化、データ抽出、または認証情報へのアクセスを試みるコマンドを実行する前に:

  1. ユーザーに正確なターゲット URL、IP、アカウント、またはリソースを述べてもらいます。
  2. ユーザーに書面による許可と許可されたスコープを確認してもらいます。
  3. 正確なコマンドを示し、その予想される効果を説明します。
  4. 現在の会話で明示的な確認を待ちます。

その確認がない場合は、読み取り専用のままにし、防御的なガイダンスのみを提供してください。サンドボックス、使い捨て VM、または管理されたラボを優先してください。

許可された使用のみ: このスキルは、許可されたセキュリティ評価、防御的検証、または管理された教育環境でのみ使用してください。

IDOR 脆弱性テスト

目的

Web アプリケーションにおける安全でない直接オブジェクト参照(IDOR)脆弱性を特定および悪用するための体系的な方法論を提供します。このスキルは、データベースオブジェクト参照と静的ファイル参照の両方、パラメータ操作と列挙を使用した検出技術、Burp Suite による悪用、および不正アクセスからアプリケーションを保護するための修復戦略を扱います。

入力 / 前提条件

  • ターゲット Web アプリケーション: ユーザー固有のリソースを持つアプリケーションの URL
  • 複数のユーザーアカウント: クロスユーザーアクセスを検証するための少なくとも 2 つのテストアカウント
  • Burp Suite またはプロキシツール: リクエスト操作のためのインターセプトプロキシ
  • 許可: セキュリティテストのための書面による許可
  • アプリケーションフローの理解: オブジェクトがどのように参照されるか(ID、ファイル名)の知識

出力 / 成果物

  • IDOR 脆弱性レポート: 発見されたアクセス制御バイパスの文書化
  • 概念実証: ユーザーコンテキストをまたぐ不正なデータアクセスの証拠
  • 影響を受けるエンドポイント: 脆弱な API エンドポイントとパラメータのリスト
  • 影響評価: データ露出の重大度の分類
  • 修復の推奨事項: 特定された脆弱性に対する具体的な修正

コアワークフロー

1. IDOR 脆弱性の種類を理解する
データベースオブジェクトへの直接参照

アプリケーションがユーザー制御可能なパラメータを介してデータベースレコードを参照する場合に発生します:

# Original URL (authenticated as User A)
example.com/user/profile?id=2023

# Manipulation attempt (accessing User B's data)
example.com/user/profile?id=2022
静的ファイルへの直接参照

アプリケーションが列挙可能なファイルパスまたは名前を公開する場合に発生します:

# Original URL (User A's receipt)
example.com/static/receipt/205.pdf

# Manipulation attempt (User B's receipt)
example.com/static/receipt/200.pdf
2. 偵察とセットアップ
複数のテストアカウントを作成する
Account 1: "attacker" - Primary testing account
Account 2: "victim" - Account whose data we attempt to access
オブジェクト参照を特定する

以下を含むリクエストをキャプチャして分析します:

  • URL 内の数値 ID: /api/user/123
  • パラメータ内の数値 ID: ?id=123&action=view
  • リクエストボディ内の数値 ID: {"userId": 123}
  • ファイルパス: /download/receipt_123.pdf
  • GUID/UUID: /profile/a1b2c3d4-e5f6-...
ユーザー ID をマッピングする
# Access user ID endpoint (if available)
GET /api/user-id/

# Note ID patterns:
# - Sequential integers (1, 2, 3...)
# - Auto-incremented values
# - Predictable patterns
3. 検出技術
URL パラメータの操作
# Step 1: Capture original authenticated request
GET /api/user/profile?id=1001 HTTP/1.1
Cookie: session=attacker_session

# Step 2: Modify ID to target another user
GET /api/user/profile?id=1000 HTTP/1.1
Cookie: session=attacker_session

# Vulnerable if: Returns victim's data with attacker's session
リクエストボディの操作
# Original POST request
POST /api/address/update HTTP/1.1
Content-Type: application/json
Cookie: session=attacker_session

{"id": 5, "userId": 1001, "address": "123 Attacker St"}

# Modified request targeting victim
{"id": 5, "userId": 1000, "address": "123 Attacker St"}
HTTP メソッドの切り替え
# Original GET request may be protected
GET /api/admin/users/1000 → 403 Forbidden

# Try alternative methods
POST /api/admin/users/1000 → 200 OK (verify protected data/action and policy)
PUT /api/admin/users/1000 → 200 OK (verify protected data/action and policy)
4. Burp Suite による悪用
手動による悪用
1. Configure browser proxy through Burp Suite
2. Login as "attacker" user
3. Navigate to profile/data page
4. Enable Intercept in Proxy tab
5. Capture request with user ID
6. Modify ID to victim's ID
7. Forward request
8. Observe response for victim's data
Intruder による自動列挙
1. Send request to Intruder (Ctrl+I)
2. Clear all payload positions
3. Select ID parameter as payload position
4. Configure attack type: Sniper
5. Payload settings:
   - Type: Numbers
   - Range: 1 to 10000
   - Step: 1
6. Start attack
7. Analyze responses for 200 status codes
複数位置に対するバタリングラム攻撃
# When same ID appears in multiple locations
PUT /api/addresses/§5§/update HTTP/1.1

{"id": §5§, "userId": 3}

Attack Type: Battering Ram
Payload: Numbers 1-1000
5. 一般的な IDOR の発生箇所
API エンドポイント
/api/user/{id}
/api/profile/{id}
/api/order/{id}
/api/invoice/{id}
/api/document/{id}
/api/message/{id}
/api/address/{id}/update
/api/address/{id}/delete
ファイルダウンロード
/download/invoice_{id}.pdf
/static/receipts/{id}.pdf
/uploads/documents/{filename}
/files/reports/report_{date}_{id}.xlsx
クエリパラメータ
?userId=123
?orderId=456
?documentId=789
?file=report_123.pdf
[email protected]

クイックリファレンス

IDOR テストチェックリスト
テスト方法脆弱性の指標
ID の増減id=5 を id=4 に変更別のユーザーのデータが返される
被害者の ID を使用既知の被害者 ID に置き換える被害者のリソースへのアクセスが許可される
範囲を列挙ID 1〜1000 をテスト他のユーザーの有効なレコードが見つかる
負の値id=-1 または id=0 をテスト想定外のデータやエラーが発生する
大きな値id=99999999 をテストシステム情報が漏えいする
文字列 ID形式を id=user_123 に変更ロジックが回避される
GUID の操作UUID の一部を変更予測可能な UUID パターンが見つかる
レスポンスの分析
ステータスコード解釈
200 OKIDOR の可能性があります。データの所有者を確認してください
403 Forbiddenこのリクエストは拒否されましたが、全体的な認可が適切に実装されている証拠にはなりません
404 Not Foundリソースが存在しないか、意図的に隠されています。認可された所有者のセッションで確認してください
401 Unauthorized認証が必要です
500 Error入力検証の問題の可能性があります
脆弱性がよく見られるパラメーター
パラメーターの種類例
ユーザー識別子userId、uid、user_id、account
リソース識別子id、pid、docId、fileId
注文/トランザクションorderId、transactionId、invoiceId
メッセージ/通信messageId、threadId、chatId
ファイル参照filename、file、document、path

制約と制限

運用上の境界
  • 検証には、少なくとも 2 つの有効なユーザーアカウントが必要です
  • ID の代わりにセッションに紐づくトークンを使用するアプリケーションもあります
  • GUID/UUID の参照は列挙が困難ですが、不可能ではありません
  • レート制限により、列挙の試行が制限される場合があります
  • IDOR の悪用には、脆弱性を連鎖させる必要がある場合があります
検出上の課題
  • 水平権限昇格(ユーザーから別のユーザーへ)と垂直権限昇格(ユーザーから管理者へ)
  • アクセスを確認できるレスポンスが返らないブラインド IDOR
  • 非同期処理における時間ベースの IDOR
  • WebSocket 通信における IDOR
法的要件
  • 明示的な許可を得たアプリケーションのみをテストしてください
  • すべてのテスト作業と調査結果を記録してください
  • 実際のユーザーデータにアクセス、変更、または持ち出しをしないでください
  • 適切な脆弱性開示窓口を通じて調査結果を報告してください

例

例 1:基本的な ID パラメーターの IDOR
# Login as attacker (userId=1001)
# Navigate to profile page

# Original request
GET /api/profile?id=1001 HTTP/1.1
Cookie: session=abc123

# Response: Attacker's profile data

# Modified request (targeting victim userId=1000)
GET /api/profile?id=1000 HTTP/1.1
Cookie: session=abc123

# Vulnerable Response: Victim's profile data returned!
例 2:住所更新エンドポイントにおける IDOR
# Intercept address update request
PUT /api/addresses/5/update HTTP/1.1
Content-Type: application/json
Cookie: session=attacker_session

{
  "id": 5,
  "userId": 1001,
  "street": "123 Main St",
  "city": "Test City"
}

# Modify userId to victim's ID
{
  "id": 5,
  "userId": 1000,  # Changed from 1001
  "street": "Hacked Address",
  "city": "Exploit City"
}

# Verify actual state in the second controlled account; 200 alone is not proof.
例 3:静的ファイルの IDOR
# Download own receipt
GET /api/download/5 HTTP/1.1
Cookie: session=attacker_session

# Response: PDF of attacker's receipt (order #5)

# Attempt to access other receipts
GET /api/download/3 HTTP/1.1
Cookie: session=attacker_session

# Vulnerable Response: PDF of victim's receipt (order #3)!
例 4:Burp Intruder による列挙
# Configure Intruder attack
Target: PUT /api/addresses/§1§/update
Payload Position: Address ID in URL and body

Attack Configuration:
- Type: Battering Ram
- Payload: Numbers 0-20, Step 1

Body Template:
{
  "id": §1§,
  "userId": 3
}

# Analyze results:
# - 200 responses require controlled-account state verification
# - Check victim's account for new addresses
例 5:水平権限昇格から垂直権限昇格へ
# Step 1: Enumerate user roles
GET /api/user/1 → {"role": "user", "id": 1}
GET /api/user/2 → {"role": "user", "id": 2}
GET /api/user/3 → {"role": "admin", "id": 3}

# Step 2: Access admin functions with discovered ID
GET /api/admin/dashboard?userId=3 HTTP/1.1
Cookie: session=regular_user_session

# If accessible: Vertical privilege escalation achieved

トラブルシューティング

問題:すべてのリクエストが 403 Forbidden を返す

原因:サーバー側のアクセス制御が実装されています 解決策:

# Try alternative attack vectors:
1. HTTP method switching (GET → POST → PUT)
2. Add X-Original-URL or X-Rewrite-URL headers
3. Try parameter pollution: ?id=1001&id=1000
4. URL encoding variations: %31%30%30%30 for "1000"
5. Case variations for string IDs
問題:アプリケーションが連番 ID ではなく UUID を使用している

原因:ランダム化された識別子によって列挙のリスクが低減されます 解決策:

# UUID discovery techniques:
1. Check response bodies for leaked UUIDs
2. Search JavaScript files for hardcoded UUIDs
3. Check API responses that list multiple objects
4. Look for UUID patterns in error messages
5. Try UUID v1 (time-based) prediction if applicable
問題:セッショントークンがユーザーに紐づいている

原因:アプリケーションがセッションと要求されたリソースの整合性を検証しています 解決策:

# Advanced bypass attempts:
1. Test for IDOR in unauthenticated endpoints
2. Check password reset/email verification flows
3. Look for IDOR in file upload/download
4. Test API versioning: /api/v1/ vs /api/v2/
5. Check mobile API endpoints (often less protected)
問題:レート制限によって列挙がブロックされる

原因:アプリケーションがリクエストのスロットリングを実装しています 解決策:

# Bypass techniques:
1. Add delays between requests (Burp Intruder throttle)
2. Rotate IP addresses (proxy chains)
3. Target specific high-value IDs instead of full range
4. Use different endpoints for same resources
5. Test during off-peak hours
問題:IDOR の影響を確認できない

原因:レスポンスからデータの所有者を明確に判断できません 解決策:

# Verification methods:
1. Create unique identifiable data in victim account
2. Look for PII markers (name, email) in responses
3. Compare response lengths between users
4. Check for timing differences in responses
5. Use secondary indicators (creation dates, metadata)

修正ガイダンス

適切なアクセス制御を実装する
# Django example - validate ownership
def update_address(request, address_id):
    address = Address.objects.get(id=address_id)
    
    # Verify ownership before allowing update
    if address.user != request.user:
        return HttpResponseForbidden("Unauthorized")
    
    # Proceed with update
    # Application-specific allowlisted validation; never pass arbitrary request fields.
    address.street = validated_street
    address.city = validated_city
    address.save(update_fields=["street", "city"])
間接参照を使用する
# Instead of: /api/address/123
# Use: /api/address/current-user/billing

def get_address(request):
    # Always filter by authenticated user
    address = Address.objects.filter(user=request.user).first()
    return address
サーバー側で検証する
# Always validate on server, never trust client input
def download_receipt(request, receipt_id):
    receipt = Receipt.objects.filter(
        id=receipt_id,
        user=request.user  # Critical: filter by current user
    ).first()
    
    if not receipt:
        return HttpResponseNotFound()
    
    return FileResponse(receipt.file)

使用する場面

このスキルは、概要に記載されたワークフローまたは操作を実行する際に適用できます。

許可された2つのテストアカウントに属する既知のオブジェクトを使用してください。列挙範囲はラボでの例示であり、任意のレコードをスキャンする許可を意味するものではありません。テストの前にリクエストの予算と停止条件を設定し、その範囲にないIPアドレスのローテーションや、スロットリング後の継続は行わないでください。GETリクエストでも副作用が生じることがあります。UUIDのランダム性は認可の代わりにはならず、UUIDを総当たりで見つけることは一般に現実的ではありません。レスポンスの長さ、タイミング、ステータスは手がかりであり、影響の証明ではありません。Djangoの例では、認証、メソッド、CSRFの処理と入力検証を省略しています。検証済みのフィールドを定義し、使用前にオブジェクトの欠落に対処してください。合成カナリアデータを使って必要最小限のアクセスのみを実証し、許可されたテストでの変更を元に戻してください。

コメント