September 26, 2026
One ID Was All It Took: How I Found an Unauthenticated IDOR
Hello Guyzzzzzzzz, It’s me again… your Chota-mota H@ck3r :)

By Aanchal Singh Rajawat
2 min read
This time, I wasn't doing anything fancy — no crazy payloads, no complicated exploit chain. I just saw an ID and thought, "What if I change this?"
Well… the server answered with 200 OK and someone else's order details. 👀
That tiny curiosity led me to an unauthenticated IDOR exposing customer PII — and things got even more interesting when I found the same authorization issue across multiple tenants.
So, here's the story of how changing one ID was enough to break an authorization boundary.
The Discovery
While browsing the application, I noticed an order-details endpoint that looked roughly like this:
GET /order-details/<ORDER_ID>
Host: tenant-a.example.comGET /order-details/<ORDER_ID>
Host: tenant-a.example.comWhenever I see an ID inside a URL, my bug hunter brain immediately asks:
"Does the server actually check who owns this?"
So I intercepted the request in Burp Suite and started testing.
First, I removed the authenticated session.
I expected:
401 Unauthorized401 Unauthorizedor maybe:
403 Forbidden403 ForbiddenInstead…
200 OK.
And the order details were still there.
Interesting.
Changing the ID
Next, I replaced the original order identifier with another valid order identifier.
GET /order-details/<ANOTHER_ORDER_ID>
Host: tenant-a.example.comGET /order-details/<ANOTHER_ORDER_ID>
Host: tenant-a.example.comThe response again returned:
200 OK200 OKBut this time, the data belonged to another customer.
The response exposed information such as:
- Customer name
- Email address
- Phone number
- Billing/shipping information
- Products and pricing
- Order status
- Payment-related information
And remember: no authenticated session was required.
At this point, it was clear that the backend was retrieving orders based on the supplied identifier without properly checking whether the requester was authorized to access them.
Then I Checked Another Tenant
The application used multiple tenant environments, conceptually like:
tenant-a.example.com
tenant-b.example.comtenant-a.example.com
tenant-b.example.comSo naturally, the next question was:
"Okay… does the same thing happen there too?"
I tested the same request against another tenant within the authorized testing scope.
Yep.
The same access-control flaw could be reproduced there as well.
Why This Happens
The vulnerable backend logic was effectively behaving like:
order = findOrder(orderId)
return orderorder = findOrder(orderId)
return orderBut it should have been closer to:
order = findOrder(orderId)
if requester is not authorized to access order:
deny()
return orderorder = findOrder(orderId)
if requester is not authorized to access order:
deny()
return orderThe server knew which order I wanted.
It just forgot to ask the important question:
"Should this person be allowed to see it?"
Impact
Because the endpoint was accessible without authentication, anyone who could obtain a valid order reference could potentially access information belonging to another customer.
More importantly,
I was able to use an order ID from a domain where I had an account against another domain where I had no account, and the server still returned the order data.
This demonstrated a cross-tenant authorization/isolation issue, in addition to the unauthenticated IDOR.
The impact included customer PII exposure, order information disclosure, and cross-tenant data access.
I only accessed the minimum data necessary to confirm the vulnerability. There is no reason to dump hundreds of customer records just to prove the vulnerability.
Takeaway
One habit that has helped me find authorization bugs is paying attention whenever I see:
/user/<ID>
/order/<ID>
/invoice/<ID>
/document/<UUID>/user/<ID>
/order/<ID>
/invoice/<ID>
/document/<UUID>Then I ask:
Can I change it?
Can another account access it?
Can I access it without authentication?
What about another tenant?
Sometimes you need a complicated exploit chain.
Sometimes you just change an ID.
And the server says:
200 OK. :)