Practice Log 06: Checking Access with Unpredictable IDs

I completed PortSwigger’s “User ID Controlled By Request Parameter, With Unpredictable User IDs” lab on October 29 as part of my PWPA preparation.
This lab felt familiar and easy after the practice I had done throughout the week.
It was quick overall, with another opportunity to examine how an application keeps one user’s private account data separate from another’s.
The difference this time was the identifier.
The application used GUIDs rather than simple, sequential user IDs.
An unpredictable identifier can make guessing another account’s ID much harder.
The application still needs to decide whether the signed-in user is allowed to access the account that identifier refers to.
OWASP’s IDOR guidance makes that distinction clear.
I used Burp Suite to inspect the account flow and review the response.
During the test, I retained the original signed-in user’s session and changed only the account identifier.
The response contained another user’s username and API key.
That content was the evidence of unauthorized access across accounts.
A successful HTTP status alone would not have established the same finding.
I submitted the lab’s required answer and saw it marked Solved.
My initial notes put too much focus on the application exposing a GUID.
After reviewing them, I tightened the explanation: a public-facing identifier can be part of a legitimate feature.
Knowing it should still leave the private account protected.
Removing that identifier from one page would not establish that the account endpoint was secure.
The important question is what happens when someone already knows the correct ID.
I also revised the impact statement. The demonstrated impact was disclosure of another user’s API key.
Further use of that key could have consequences depending on its permissions, but my evidence does not establish those capabilities or how activity would appear in the logs.
For remediation, I would derive the signed-in identity from a trusted session and enforce permission checks for the requested account before returning private data.
A self-account endpoint could retrieve the account directly from that identity.
Where an account reference is accepted, the server should verify ownership or another explicit permission and deny access otherwise.
This follows OWASP’s authorization guidance.
For regression testing, I would check that:
- Each signed-in user can still access their own account.
- A user who supplies another account’s correct GUID cannot retrieve its private data.
- Denied responses contain none of the other account’s sensitive information.
- Unauthenticated requests cannot retrieve private account data.
- Intended public features, such as author links, continue to work without exposing private account details.
I would also review authorization logging without recording API keys or session cookies.
Logging would support detection and investigation alongside the permission checks.
These are proposed remediation and regression checks.
I have not implemented a fix or run those tests against a corrected version of the lab.
The exercise was straightforward.
Reviewing the write-up helped me make the finding more precise: record the session, the changed input, the returned data, and the limits of what the evidence proves.
If you’re practicing this exercise, use PortSwigger’s authorized training environment and stay within its scope.
Building a SaaS? Explore my independent security reviews