Cross an object-ownership boundary
Needs: The server accepts a lower-privilege identity's request for an object it should not access
Use two controlled lab identities and one object owned by each:
GET /api/orders/OBJECT_B HTTP/1.1
Host: DOMAIN
Authorization: Bearer USER_A_TOKEN
- Save user A's successful request for object A.
- Change only the path/query/body object reference to object B.
- Keep A's token.
- Verify disclosure or the intended update/delete effect against B's object.
Decisive output: data or a state change belonging to B under A's context. A different error or
200wrapper is not enough.
Verify → Verify object ownership, requesting identity and the actual unauthorized effect.
If it fails → A 200 response may be a generic page or public object. Validate ownership and intended access before drawing a conclusion. More detail ↓
Explanation & examples
Cross an object-ownership boundary
- USE WHEN
- A request selects an object by ID/path and two authorized ownership contexts are available
- STARTING ACCESS
- A reproducible application request and a controlled input or access-context comparison
- RESULT
- Verified unauthorized object read or modification
Recognize the clue
Capture object requests for two authorized study accounts and associate each object ID with its owner before making a cross-account comparison.
curl -sk -b lower-role.cookies http://TARGET:PORT/api/objects/OBJECT_ID
Request identity: USER_A
Object metadata: owner=USER_B
Response: private object bytesMeans: A private object owned by another controlled account is returned to the lower-context requester.
Confirm: Confirm intended sharing rules, account isolation and actual object content/change with valid controls.
- After validation
- The action crosses a real ownership boundary: use the demonstrated read/write primitive.
- Ruled out in this context
- The object is intentionally public/shared: reject unauthorized-access inference from its ID alone.
- Still inconclusive
- Unknown ownership or identical generic pages leave the access claim unproved.
Troubleshooting: A 200 response may be a generic page or public object. Validate ownership and intended access before drawing a conclusion.
Use two controlled lab identities and one object owned by each:
- Save user A's successful request for object A.
- Change only the path/query/body object reference to object B.
- Keep A's token.
- Verify disclosure or the intended update/delete effect against B's object.
Decisive output: data or a state change belonging to B under A's context. A different error or
200wrapper is not enough.
Why it works
Knowing or guessing an identifier is not the flaw; missing server-side authorization on the selected object is. Public objects and intentionally shared data need different expected behavior.
Worked example · hypothetical
Observation: account A can request account B's object ID. Test: compare owner, lower-role and unauthenticated controls. Illustrative output: A receives B's private document. Interpretation: object-level read is confirmed; inspect the document's useful artifacts.
New identity, privilege, host or route? Re-enumerate → All topic tasks →