top of page

Case study Broken access control

During audits, we discovered multiple issues in the /internal/profile endpoint, used by the web app to fetch customer details. The endpoint accepted a profile_id parameter and returned full profile data without verifying that the requesting user actually owned that profile. By incrementing or iterating over profile_id values, an authenticated user could enumerate other customers’ records and retrieve PII (name, email, phone, partial address) under certain conditions.


Escalation to impersonation. Although passwords weren’t exposed, combining this PII with weak secondary controls created a realistic impersonation path:

  • The attacker enumerated profile IDs and collected PII for multiple users.

  • The application’s account recovery and customer support flows relied heavily on this same PII for identity verification (e.g., name + email + last digits of phone).

  • With sufficient PII, the attacker could pass “knowledge-based” checks and request actions on victims’ accounts (manual password reset via support, changes to contact info, disabling MFA, etc.).

In other words, a “simple” BOLA/IDOR on an internal API became a business‑level impersonation and account takeover risk, not just a privacy issue.



The flow goes like - "in internal API → PII exposure → impersonationFinding (short narrative).During an internal API assessment, if we identified a Broken Object Level Authorization (BOLA)"



Why this is key in most modern web apps

  • Modern SPAs and mobile apps are front‑ends for dense internal APIs; most business logic and access control lives server‑side.

  • APIs often expose object IDs (user, order, document, tenant) and rely on the client to “only request its own data,” which is insecure by design.

  • Business processes frequently reuse PII from those APIs as identity proof (support, KYC, recovery), so PII enumeration commonly escalates to impersonation, fraud, or regulatory incidents.

That’s why Broken Access Control and BOLA sit at the top of OWASP’s web and API risk lists today.


  1. Enforce object‑level authorization on the server

    • Every request to /internal/profile must check: “Is profile_id owned by the currently authenticated user (or within their tenant/role)?”

    • Example pattern (pseudo‑code):

      • Extract user_id from the session/JWT.

      • Query profile where profile.id = profile_id AND profile.owner_id = user_id.

      • If no row, return 404 or 403 without leaking existence.

  2. Avoid predictable object identifiers where possible

    • Replace sequential IDs with non‑guessable identifiers (UUIDs or tenant‑scoped tokens), so enumeration is harder.​

    • Do not rely solely on “hard to guess” IDs; this complements, not replaces, authorization.

  3. Minimize PII returned

    • Return only the attributes strictly required for the client’s current view or workflow.

    • Strip sensitive fields from any “lookup” or list endpoints.

  4. Harden identity verification flows

    • Do not rely on static PII alone for support / recovery flows; mix in strong factors (email links, SMS, app-based confirmation, or MFA) for critical actions.

    • Align KYC / support scripts with the new access‑control model to prevent social engineering using leaked PII.





Previously found public cases can be found on - https://hackerone.com/craxermgr?type=user

Comments


bottom of page