← All case studies

16 Oct 2026 · 5 min read

Mass IDOR via Parameter Tampering & Coordinated Disclosure

How a client-side boolean flag exposed a platform-wide invoice database of nearly 10,000 records, chaining into widespread IDOR vulnerabilities and a coordinated disclosure mediated by CERT Polska.

Context & Scope#

During independent security research assessing a B2B billing and financial document management portal utilized in the enterprise workforce and subcontractor accounting sector, I investigated how the platform isolated tenant records across different worker accounts. The portal handled highly sensitive contractor records, including commercial lease agreements, weekly payout ledgers, corporate tax declarations, and government identity scans.

The primary objective of the assessment was to verify server-side authorization enforcement: specifically, whether the backend strictly derived access rights from authenticated session contexts, or whether privilege state and object filtering were influenced by client-controlled parameters.

Tools & Setup#

  • Burp Suite - intercepting XHR/Fetch API traffic, isolating endpoint parameters, and performing automated request comparison in Repeater.
  • Claude Opus - assisting in dissecting complex server-side DataTables query protocols and identifying chained parameter tampering vectors.
  • Browser DevTools (Chromium) - analyzing asynchronous network traffic, inspecting request payloads, and reviewing client-side routing logic.
  • Postman & cURL - crafting raw HTTP requests, manipulating parameter flags, and verifying access control behavior across session tokens.
  • Python scripts - verifying pagination bounds and reproducing findings with minimal, non-disruptive proof-of-concept requests.

Technical Walkthrough#

  1. Parameter Tampering on the Invoicing Service: When navigating to the contractor billing tab, the web application dispatched an asynchronous POST request to an invoice-loading endpoint (/api/v1/invoices/load). The backend utilized a server-side paginated table pattern (DataTables). Inspecting the raw payload body revealed typical pagination parameters alongside an explicit role flag:

    draw=2&start=0&length=10&userId=<my_user_id>&isAdmin=0

    To test how the backend processed this parameter, I captured the request in Postman and modified the flag value from isAdmin=0 to isAdmin=1. The backend did not cross-reference the user's actual role in the session store; instead, it evaluated the flag literally within the database query logic.

    The response returned HTTP 200 OK with a JSON payload containing "recordsTotal": 9675 and "recordsFiltered": 9675—effectively dumping the platform's entire global invoice registry, complete with gross payout sums, contractor tax identifiers, bank account numbers, and personal UUIDs.

Manipulating the isAdmin flag in Postman to return global invoice records
  1. Harvesting Identifiers & Chaining IDORs: The mass invoice disclosure exposed thousands of valid internal user identifiers (userId). In modern API architectures, UUIDs are frequently treated as pseudo-secrets; however, relying on UUID obscurity without object-level permission checks creates systemic vulnerability. Armed with legitimate UUIDs from the invoice leak, I evaluated auxiliary document and profile endpoints:

    • Contract Management (/api/v1/contracts/view): Substituting another contractor's userId in the request body permitted downloading signed employment agreements, vehicle leases, tax forms, and termination notices without any validation against the requester's session.
    • Vehicle Fleet Documentation: Changing the identifier exposed vehicle registration cards, inspection logs, and fleet insurance certificates.
    • Attachment Retrieval (/api/v1/documents/load): Swapping identifiers returned all private files associated with the target contractor. Critically, submitting the request with the userId parameter completely omitted caused the backend query to lose its WHERE filter entirely, returning arbitrary confidential attachments from the database.
  2. Client-Side Script Reconnaissance: Inspecting unbundled client-side application scripts revealed administrative routes that had been omitted from the standard navigation interface:

    • Settlement Export Endpoint (/api/v1/settlements/list): An administrative route that allowed any authenticated basic user to view, export, and delete weekly driver payroll spreadsheets in CSV format.
    • Driver Broadcast Announcements (/api/v1/announcements/create): An unvalidated endpoint that permitted creating and publishing platform-wide announcements directly onto the main dashboard of all registered drivers.
http
POST /api/v1/invoices/load HTTP/1.1
Host: portal.target-platform.local
Authorization: Bearer <low_privileged_user_token>
Content-Type: application/x-www-form-urlencoded

draw=2&start=0&length=25&userId=&isAdmin=1
http
POST /api/v1/documents/load HTTP/1.1
Host: portal.target-platform.local
Authorization: Bearer <low_privileged_user_token>
Content-Type: application/json

{
  "userId": "<leaked_target_user_uuid>"
}

Findings & Severity#

Vector / Indicator Vulnerability Type Severity
Tampering with isAdmin parameter dumps 9,675 global invoice records Parameter Tampering / BOLA Critical
Unrestricted access to employment contracts, tax forms, and ID files via UUID Insecure Direct Object References (IDOR) Critical
Unprotected access to bulk settlement spreadsheets via unlinked routes Broken Function Level Authorization (BFLA) High
Unprivileged creation of platform-wide worker announcements Missing Function Level Access Control Medium

Responsible Disclosure & Takeaways#

Due to the sensitivity and volume of exposed contractor data (including tax IDs and employment contracts), I immediately compiled a comprehensive vulnerability report containing reproducible cURL commands, sanitized screenshots, and remediation guidance.

Initially, I reached out through the vendor's direct contact channels. However, when initial discussions stalled and the critical endpoints remained exposed in production, I escalated the case to CERT Polska to ensure coordinated vulnerability handling. CERT Polska verified the severity, established direct technical communication with the vendor's leadership, and facilitated the remediation process. Following CERT's coordination, the vendor deployed emergency patches across all production environments, revoking client-side administrative parameter handling and enforcing session-tied object ownership across all document endpoints.

From an engineering and analytical standpoint, this case underscores two critical principles:

  1. Authorization state must never be client-controlled: Trusting client-supplied parameters such as isAdmin or accepting role overrides in request bodies bypasses authentication controls. The server must derive permissions exclusively from the verified server-side session or cryptographically signed claims.
  2. Obscurity is not authorization: Relying on unguessable UUIDs or hiding administrative routes from the frontend menu is ineffective against systematic reconnaissance. Every endpoint accessing persistent data must enforce an explicit ownership check: verifying that the authenticated identity has legitimate authority over the requested record.