October 1, 2026
How Changing One Customer ID Exposed Other Users’ Pet Recommendations and Earned Me a $1,000 Bounty
Researcher: papjm Vulnerabilities: Broken Access Control and Information Disclosure Reward: $1,000

By Adini Rodini Rodney
2 min read
The company, hostname, API path, customer identifiers, database objects and triager identity have been redacted. No SQL injection was confirmed.
Summary
I discovered two related vulnerabilities in an online retailer's product-recommendation API.
First, changing a user-controlled customer_id parameter caused the API to return pet-product recommendations belonging to another customer.
Second, a Base64-encoded tracking_id in the response exposed internal SQL queries, database table names and column names.
Discovery
I signed in to my account and opened the account section while Burp Suite captured the application's traffic.
In Burp's HTTP history, I found a recommendation request containing several parameters:
GET /[REDACTED]?
category_id=[CATEGORY_ID]&
user_id=[USER_IDENTIFIER]&
customer_id=[MY_CUSTOMER_ID]GET /[REDACTED]?
category_id=[CATEGORY_ID]&
user_id=[USER_IDENTIFIER]&
customer_id=[MY_CUSTOMER_ID]I sent the request to Burp Repeater and changed only the customer_id to a nearby value:
customer_id=[ANOTHER_CUSTOMER_ID]customer_id=[ANOTHER_CUSTOMER_ID]My authenticated session and the other parameters remained unchanged.
The server returned 200 OK with a different set of pet-product recommendations associated with the supplied customer ID.
This confirmed that the server trusted the customer ID from the URL without verifying that it belonged to the authenticated user.
If customer IDs were predictable or obtainable elsewhere, an attacker could potentially automate the process and enumerate recommendations belonging to multiple customers.
The Base64-Encoded Tracking ID
While examining the response, I noticed a long value inside a field named tracking_id.
The format and padding suggested that it was Base64-encoded. Base64 is encoding — not encryption — so I decoded it.
The decoded value contained internal SQL filters similar to this sanitized example:
{
"filters": [
{
"query": "SELECT 1 FROM [INTERNAL_TABLE] WHERE [INTERNAL_CONDITIONS]",
"operation": "in"
}
]
}{
"filters": [
{
"query": "SELECT 1 FROM [INTERNAL_TABLE] WHERE [INTERNAL_CONDITIONS]",
"operation": "in"
}
]
}The data exposed internal SQL query templates, database table names and column names used by the recommendation engine.
This did not prove that the application was vulnerable to SQL injection. However, the information could help an attacker understand the database structure and prepare more targeted attacks if another injection vulnerability existed.
Impact
An attacker with a normal account could potentially:
- Access pet-product recommendations associated with other customers.
- Enumerate recommendation data by changing customer IDs.
- Learn information about another customer's pet-related interests.
- Recover internal SQL query templates from the tracking value.
- Identify database tables and columns that could support further reconnaissance.
Product recommendations may not appear highly sensitive, but this was still a cross-account authorization failure. A user should never be able to retrieve another customer's personalized data by changing a URL parameter.
Root Cause
The server accepted a client-controlled customer_id without confirming that it belonged to the authenticated session.
The client also received internal SQL information that was unnecessary for displaying recommendations.
Recommended Remediation
The application should:
- Derive the customer identity from the authenticated session.
- Enforce object-level authorization before returning personalized data.
- Reject requests for customer IDs that do not belong to the authenticated user.
- Remove SQL queries and database details from client-visible responses.
- Replace the encoded SQL data with an opaque server-generated tracking identifier.
- Monitor repeated requests involving different customer IDs.
Disclosure and Outcome
I reported the vulnerabilities through the company's bug-bounty program.
The security team reviewed the evidence, triaged the report and awarded me a $1,000 bounty on February 9, 2024.
Takeaway
Whenever a request contains multiple identity-related parameters, change them one at a time and compare the responses carefully.
Also inspect values named tracking, metadata, debug, state or context. Data that appears opaque may simply be encoded.
The most important lesson is that personalized data must be selected using a server-verified identity — not an identifier controlled by the client.