Multi-Role IDOR Testing

PhantomYerra tests Insecure Direct Object References and privilege escalation across all credential combinations simultaneously - horizontal access (user A reading user B's data) and vertical escalation (user gaining admin access).

What Are IDOR and Privilege Escalation?

Insecure Direct Object Reference (IDOR) occurs when an application exposes internal object identifiers - such as database IDs, UUIDs, or sequential numbers, in API endpoints or parameters, without verifying that the requesting user is authorised to access the referenced object.

OWASP classifies IDOR under Broken Access Control (A01:2021): the number one web application security risk. It is consistently the most common high-severity finding in real-world penetration tests.

Horizontal Privilege Escalation

User A accesses resources belonging to User B, where both have the same role. Example: a regular user reads another regular user's private messages, invoices, or medical records by changing an ID in the URL.

GET /api/invoices/10042   → returns YOUR invoice
GET /api/invoices/10043   → returns ANOTHER USER'S invoice (IDOR)

Vertical Privilege Escalation

A lower-privileged user accesses functionality or data reserved for a higher-privileged role. Example: a regular user calls an admin-only endpoint by using their own session token.

GET /api/admin/users      → should require admin role
# Attempted with regular user token → HTTP 200 (VERTICAL ESCALATION)

Why Multiple Credential Sets Are Required

To test both horizontal and vertical escalation comprehensively, PhantomYerra needs credentials representing each distinct role in the application. Without multiple sessions, it is impossible to verify whether:

Minimum recommended: 2 user accounts (same role, different data) + 1 admin account + 1 unauthenticated (no token). This covers all four escalation vectors PhantomYerra tests.

Configuring 4 Credential Sets

1

Open the Multi-Role Configuration Panel

In the Scan Wizard, on the Authentication step, click Add Multiple Roles. This expands the credential matrix panel.

2

Add User A (Standard Role - owns test data)

Enter credentials for your first standard user. This is the account that "owns" test resources. PhantomYerra will authenticate as User A first to discover resource IDs, then switch sessions to test cross-user access.

Label: USER_A - Role: standard

3

Add User B (Same Role - should NOT access User A's data)

A second standard user with the same permissions as User A but no ownership of User A's resources. PhantomYerra will attempt to access User A's resources using User B's session.

Label: USER_B - Role: standard

4

Add Admin Account

An administrator account. PhantomYerra maps which endpoints return different data or allow different actions for admins, then tests whether standard users can access those same endpoints.

Label: ADMIN - Role: admin/superuser

5

Add Unauthenticated Session

PhantomYerra automatically includes an unauthenticated (no-token) session to detect authentication bypasses - endpoints that should require login but respond to unauthenticated requests.

Label: UNAUTH - No token

Multi-Role Credential Matrix Table with 4 rows: USER_A (standard, green), USER_B (standard, green), ADMIN (red badge), UNAUTH (grey). Each row shows: username, role label, auth method (Bearer/Cookie/API Key), token status (Active/Pending), and a "Test Connection" button. Bottom: "Run IDOR Matrix Scan" button.

What PhantomYerra Tests Automatically

Phase 1 - Resource Discovery (authenticated as USER_A)
  → Crawl all authenticated endpoints
  → Extract all object IDs from URLs, request bodies, responses
  → Build resource map: {endpoint → [id_list]} for USER_A's objects

Phase 2 - Horizontal IDOR (USER_B accessing USER_A's IDs)
  → Replay every USER_A request using USER_B session token
  → Compare HTTP status + response body
  → [IDOR] GET /api/documents/9921 with USER_B token → HTTP 200 (USER_A's document returned)
  → [OK] GET /api/invoices/10042 with USER_B token → HTTP 403 (correct rejection)

Phase 3 - Vertical Escalation (USER_A/B accessing ADMIN endpoints)
  → Map all endpoints accessed by ADMIN session
  → Replay with USER_A and USER_B tokens
  → [VERTICAL] GET /api/admin/users with USER_A token → HTTP 200 (admin data returned)

Phase 4 - Auth Bypass (UNAUTH accessing protected endpoints)
  → Replay all authenticated endpoints with no token
  → [AUTH BYPASS] GET /api/reports/summary → HTTP 200 without any auth token

Phase 5: ID Enumeration
  → Sequential ID fuzzing around discovered IDs
  → UUID structure analysis for predictability
  → [IDOR] IDs are sequential integers 10040–10099, full database enumerable

Interpreting IDOR Test Results

CRITICAL

Horizontal IDOR - Cross-User Data Access

USER_B successfully retrieved USER_A's private document via GET /api/documents/9921. Response included full document content, owner name, and metadata. Any authenticated user can enumerate and read all other users' documents by iterating the integer ID.

CRITICAL

Vertical Escalation - Standard User Accessing Admin Panel

GET /api/admin/users with USER_A's standard session token returned the full user list including hashed passwords, email addresses, and last login timestamps. Admin authorisation check missing on this endpoint.

HIGH

Authentication Bypass - Unauthenticated Access to Reports

GET /api/reports/summary returns executive dashboard data without any authentication token. The middleware auth check is missing on the /reports/* route group.

MEDIUM

Sequential Integer IDs - Full Enumeration Possible

All resource IDs use sequential integers starting from 1. Even with proper access controls, this allows an attacker to determine how many resources exist in the database and probe for missing access control gaps methodically.

PoC Example - Confirmed IDOR

# IDOR - Cross-user invoice access
# Confirmed: USER_B can read USER_A's invoices

# Step 1: Authenticate as USER_A, discover invoice ID
curl -X GET "https://app.example.com/api/invoices" \
  -H "Authorization: Bearer USER_A_TOKEN" \
  | jq '.[0].id'
# → 10042

# Step 2: Switch to USER_B session, access USER_A's invoice
curl -X GET "https://app.example.com/api/invoices/10042" \
  -H "Authorization: Bearer USER_B_TOKEN"

# Expected: HTTP 403 Forbidden
# Actual: HTTP 200: returns full invoice for USER_A
# {
#   "id": 10042,
#   "owner": "user_a@example.com",
#   "amount": 4299.00,
#   "card_last4": "4242",
#   ...
# }

Remediation Guidance

Finding TypeRoot CauseFix
Horizontal IDOR Resource fetched by ID without owner verification Add WHERE owner_id = current_user.id to every resource query. Never trust client-supplied IDs alone.
Vertical Escalation Role check missing or bypassed on privileged endpoint Apply role middleware (require_role('admin')) at the route level, not just the handler. Use deny-by-default.
Auth Bypass Authentication middleware not applied to route group Apply require_auth middleware globally, then whitelist public routes explicitly. Never add auth per-route.
Sequential IDs Auto-increment integer primary keys exposed in API Use UUIDs (v4) or KSUID as public-facing identifiers. Keep integer IDs internal to the database only.