Sanitized finding from Client R. Identifiers, roles and business records are generalized.
Context
The application exposed account and document operations through API routes that accepted client-controlled identifiers.
Finding
The server did not consistently enforce the relationship between the authenticated principal, the requested object and the requested action. Changing an identifier exposed account impersonation behavior and allowed access to records outside the expected authorization boundary.
Technical workflow
The authorization matrix covered same-tenant peers, cross-tenant objects and privileged targets. The request below uses synthetic identifiers and an approved test token:
curl --fail-with-body --max-time 5 \
-H 'Authorization: Bearer TEST_TOKEN_A' \
'https://AUTHORIZED_HOST/api/resources/TEST_OBJECT_B'
For an object owned by another principal, the expected result is a uniform 403 or 404, with no difference that reveals whether the object exists. The policy belongs on the server:
def authorize(principal, resource, action: str) -> None:
if resource.tenant_id != principal.tenant_id:
raise PermissionError("cross-tenant access denied")
if action not in principal.allowed_actions(resource):
raise PermissionError("action not permitted")
if resource.subject_id != principal.subject_id and action == "impersonate":
raise PermissionError("subject binding required")
The same check must run for reads, exports, mutations and impersonation-token issuance. Client-side hidden fields or opaque identifiers are not authorization controls.
Impact
An authenticated user could act on behalf of another account or retrieve business documents they were not authorized to access. The impact included confidentiality loss, unauthorized workflow actions and possible account takeover chains.
Remediation
- Enforce authorization server-side for every object and action, including impersonation flows.
- Bind tokens and session state to the approved subject and target account.
- Replace client-trusted identifiers with policy-checked references where possible.
- Add horizontal and vertical authorization tests to CI and log sensitive subject changes.
Validation
Test cross-tenant, peer-role and privileged-role combinations. Every unauthorized object or action must return the same safe denial without leaking record existence.
Record the principal, target object, action and policy decision in an integrity-protected audit trail. A denial in the UI but a successful direct API call remains a failed retest.