A Hidden Endpoint and 5,000 Records
While exploring the scope of a large bug bounty program, I came across a promotional microsite built for an in-person event. Unlike most microsites, this one didn’t have any interesting subdomains to enumerate. There was just a single domain and a simple application.
The entire purpose of the site was to allow users to register for an event related to one of the platform’s shows. Visitors were required to provide information such as:
- First name
- Last name
- National identification number
- Email address
- Phone number
Submitting the form caused the frontend to send a request to:
POST /_submit
and, if everything went well, the server simply responded with a 200 OK.
Nothing particularly interesting.
As usual, I started looking through the JavaScript files in search of hidden endpoints, API keys, or anything that might have been left behind.
One path immediately caught my attention:
/api/data/data
Naturally, my first instinct was to issue a GET request.
Instead of anything interesting, the server replied with:
{
"status": 400,
"message": "No"
}
I tried all the usual things:
- Different HTTP methods.
- Case variations.
- URL encoding.
Anything that might turn the response into something useful.
Nothing worked.
At that point, I had no idea what the endpoint was supposed to do, but the path itself looked suspicious enough that I wasn’t ready to completely give up on it. So I played the waiting game.
Since I don’t have any automation in place, I simply checked the endpoint manually once or twice a day. For two days, nothing changed.
On the third day, after the registration period had already ended, I decided to send one more request without expecting much. This time, the server answered with a 200 OK.
Technical Details
A GET request to:
GET /api/data/data
returned a JSON response containing more than 5,000 records.
No authentication.
No session cookie.
No API token.
Nothing.
Each record contained sensitive personally identifiable information, including:
- Full names
- National identification numbers
- Email addresses
- Phone numbers
- Birth dates
The response looked similar to:
{
"status": 200,
"message": "success",
"data": [
{
"id": 1,
"createdAt": "2026-02-09T16:03:39.535Z",
"dni": "[REDACTED]",
"name": "[REDACTED]",
"lastName": "[REDACTED]",
"birthDate": "[REDACTED]",
"email": "[REDACTED]",
"phone": "[REDACTED]",
"companion": 0
}
]
}
The endpoint could be accessed directly from a browser and required no authorization whatsoever.
In other words, anyone who knew the path could retrieve the entire dataset.
Impact
The exposure affected more than 5,000 users and included highly sensitive personal information.
Given the amount and sensitivity of the information involved, the issue was classified as Critical.
I submitted the report within minutes of confirming the exposure. A couple of hours later the report was accepted, and three days later the bounty had already been paid.
The remediation was exactly what I hoped for: the vulnerable endpoint was taken offline and /api/data/data stopped returning user data altogether.
This time waiting for the right moment paid off. See you in the next one :)