August 17, 2026
How an Unauthenticated API Endpoint Exposed 19,990 User Records
How a missing authorization check turned a profile API into a data exposure risk.

By Hangga Aji Sayekti
5 min read
I Changed One URL Parameter and Found PII Exposed Across 19,990 User Profiles
In June 2026, while exploring an AI-focused freelance marketplace, I stumbled upon a security issue that perfectly illustrates one of the oldest lessons in application security:
If your backend trusts the frontend, someone is eventually going to have a bad day.
The issue was reported responsibly, acknowledged by the appropriate team, and fixed. Any identifying details have been redacted.
Let's dive in.
Responsible Disclosure
Before diving into the technical details, a quick note: this issue was responsibly disclosed to the platform and received a positive response from the team.
Interestingly, this was not the only issue reported. During the same review, I ended up disclosing three separate security vulnerabilities affecting the platform. This article covers one of them; another — an email verification bypass — has already been documented in a separate write-up.
The reports were acknowledged quickly, investigated by the team, and the exposed data described in this article was no longer accessible shortly afterward.
At the time of writing, I'm still waiting for their final response — and maybe a bounty, if I'm lucky. 😄
Either way, the main objective was achieved: getting the issues into the hands of the people who could fix them before they became someone else's discovery.
The Target
The platform was an AI freelancer marketplace that helps companies find and hire AI specialists for automation projects, chatbots, and AI development.
After creating an account with a temporary email address, I started exploring the application from a regular user's perspective.
One of the first areas I looked at was the profile section. While reviewing how profile information was retrieved and displayed, I noticed an API request that would eventually lead to a much larger issue.
Step 1: Watching the Traffic
I opened devTools and started observing network requests.
Among dozens of API calls, one endpoint immediately caught my attention:
https://[redacted]/api/developer/profile-details?id=22861&devId=20939https://[redacted]/api/developer/profile-details?id=22861&devId=20939The response contained my profile information.
Pretty normal.
But security researchers have a dangerous habit:
We ask questions.
In this case:
What happens if I open this endpoint directly?
Step 2: The "Wait… Seriously?" Moment
I copied the URL. Then I opened a different browser.
Then I pasted the URL and pressed Enter.
The profile loaded successfully without requiring authentication.
At first, I suspected it might be a caching issue or some frontend quirk, so I repeated the test in a clean browser session.
The result was the same. The endpoint was publicly accessible without authentication.
At that point, it was clear this deserved a closer look.
While examining the URL more closely, I noticed that the profile identifier was a sequential integer.
Step 3: The Integer Adventure Begins
When sensitive records are exposed through sequential IDs, every security researcher has the same thought:
Surely it can't be that simple…
So I tried:
?id=0?id=0Nothing.
Then:
?id=1 → Nothing.
?id=2→ Nothing.
?id=5 → Still nothing.
?id=10 → Valid record. ✅
Now things were getting interesting.
Step 4: How Big Is This Rabbit Hole?
I decided to test a larger value.
?id=10000 → Valid record. ✅
Interesting.
I kept going.
Curious about the scale, I started jumping through the ID space instead of checking every value.
?id=11000 → valid.
?id=15000 → valid.
?id=19000 → valid.
?id=19999 → still valid.
At that point, it became clear that this wasn't an isolated exposure.
At this point I started wondering:
How many records are actually exposed?
Up to this point, everything had been done directly from a browser by modifying a few URL parameters.
No advanced tooling was required. Just a browser and elementary-school arithmetic.
Step 5: What About devId?
The endpoint also contained another parameter:
devId=20939devId=20939Initially I assumed it was some sort of authorization control.
So naturally I started changing it.
devId=10001devId=10001Nothing happened.
The same records remained accessible.
Then I discovered that certain values actually expanded the amount of information returned.
In other words:
The parameter wasn't restricting access.
It was exposing more details.
Impact
The exposed records contained personally identifiable information (PII) and other sensitive profile-related data.
The exact fields have been intentionally omitted.
However, issues like this can enable:
- Large-scale user enumeration
- Targeted phishing campaigns
- Identity correlation
- Social engineering attacks
- Privacy violations
The key issue wasn't just unauthorized access.
It was unauthorized access at scale.
Root Cause
This wasn't an advanced vulnerability.
There was no cryptography involved.
No race conditions.
No authentication bypass tricks.
The root cause was surprisingly simple:
Missing Authorization Checks
The backend returned sensitive user data without verifying whether the requester was authorized to access it.
Combined with predictable integer IDs, the result was a classic enumeration vulnerability.
Sensitive Endpoint
+
No Authorization Check
+
Sequential IDs
=
Mass Data ExposureSensitive Endpoint
+
No Authorization Check
+
Sequential IDs
=
Mass Data ExposureLessons Learned
1. Never Trust the Frontend
Attackers don't use your UI.
They interact directly with your APIs.
Authorization must always be enforced server-side.
2. Authentication Is Not Authorization
A user being logged in doesn't automatically mean they can access every resource.
Ownership and permissions must be verified for every sensitive request.
3. Sequential IDs Make Enumeration Easy
Predictable identifiers are not inherently vulnerable.
But when combined with missing authorization checks, they dramatically increase impact.
4. Small Mistakes Become Big Incidents
One missing authorization check can expose a single record.
Enumeration can turn that into thousands.
5. Browser Developer Tools Are Enough
Many impactful findings don't require advanced tooling.
Sometimes F12 is all you need.
Final Thoughts
One of the biggest myths in security is that major data exposures require sophisticated attackers.
Sometimes they don't.
Sometimes everything starts with a simple question:
What happens if I open this URL somewhere else?
In this case, that question eventually led to nearly twenty thousand accessible records.
And that's exactly why security controls must live on the backend.
Because attackers never use your UI.