Find hidden API parameters by capturing complete requests as users of different roles, reading client-side code, and checking older specs. Then probe each suspect parameter with obviously invalid values and watch whether the response comes from routing or from application logic. Report what changes, not just what errors.
What counts as hidden
A hidden parameter is one the API accepts but the public documentation does not list. Examples are debug flags, role or tenant fields, filter options meant for admin screens, and fields kept from an earlier version. They are not secret in a strong sense. They are just unadvertised, which means they usually skip review.
Where they show up
The OWASP reconnaissance guidance for API testing points to several places:
- Traffic through an intercepting proxy. Capture full requests including headers and bodies. Look for parameters, structured values in JSON or XML, and dynamic URL segments.
- Different privilege levels. Browse the app with accounts at different levels to expose more functionality, and compare the requests.
- Client-side HTML and JavaScript. Scripts often reference API paths and options that the interface never uses for a normal user.
- Older definitions. Earlier OpenAPI versions may expose deprecated but still-working endpoints and fields.
- Source code, if you have it: extract routes and handlers.
How to probe a suspect parameter
- Send the normal request and save the response as a baseline.
- Add the parameter with a clearly invalid value, such as an absurdly long string or a wrong type.
- Compare. The guidance suggests checking whether the response comes from routing or from application logic. A generic not-found or bad-request from the framework says nothing. A specific validation message from the application means the parameter is real and parsed.
- Try a harmless valid value and look for a difference in the response body, fields or order.
- Try the parameter as each role. A flag that does nothing for a regular user but changes output for an admin is worth a note.
- Try it on older API versions and alternate hosts.
Parameters that deserve special care
| Kind | Why it matters | What to check |
|---|---|---|
| Role or permission fields | Mass assignment can promote an account | Whether the server accepts and stores them |
| Tenant or owner IDs | Can cross isolation boundaries | Whether the server trusts them over the session |
| Debug or verbose flags | Can leak internal detail | Whether they work outside development |
| Filter and include options | Can widen the data returned | Whether the same authorization applies |
| Pagination limits | Can pull huge data sets | Whether a maximum is enforced |
The OWASP excessive data exposure test includes a related step: on endpoints that accept JSON or XML, add extra fields such as a role flag and see whether the server accepts them.
Keep the tests safe
Use test accounts and a test environment. Do not send destructive values. Change one thing at a time so you know what caused a difference. Log what you sent.
Make it a habit
Each time a response or request shape changes in a pull request, ask whether a new optional field appeared. New fields are the start of the next hidden parameter. Keep your spec generated from code so undocumented fields show up as drift.
Worked example: a profile endpoint with a surprise
Take a profile API with GET /api/profile and PATCH /api/profile. The public docs list the update fields: displayName, bio and timezone. A tester looks for hidden parameters.
Gather clues.
- In the proxy history, the tester notices that the web app's profile request sometimes includes
?expand=settingswhen an admin is logged in, and never for a regular user. - Reading the front-end JavaScript, the tester finds a string
"debug=true"used in a development helper, and a reference to atenantIdfield in a request builder. - An older OpenAPI file, still reachable on a staging host, lists a
rolefield on the profile update.
Three suspects: expand, debug and tenantId, plus role from the old spec.
Probe each, with a baseline. The tester saves the normal GET /api/profile response as the baseline.
| Suspect | Test | Observation | Meaning |
|---|---|---|---|
| expand=settings, as regular user | Add to GET | Response includes a settings object with notification options | Works for a regular user too. Probably fine, but check whether it includes anything sensitive |
| debug=true | Add to GET | Response gains a debugInfo block with a SQL query and server name | Debug output reachable in staging, must not exist in production |
| tenantId in PATCH body | Send another tenant's ID | Server returns 200 and the next GET shows the other tenant's profile data | Trusts a client-supplied tenant. Serious |
| role in PATCH body | Send "role": "admin" | 200, and the next GET shows role admin | Mass assignment. Serious |
Two serious findings, one moderate, one that needs a closer look. Each came from a clue rather than from random guessing.
Check production safely. The tester asks whether the same parameters exist in production. A single request with debug=true is sent with a test account, under the agreed plan. The response is the same as the baseline, so debug is off there. The role and tenantId tests are repeated only on a test tenant in production, with approval, using an account created for the purpose. They succeed. The tester stops there and reports immediately.
Fixes.
- Remove or disable
debugoutside development builds. - Make
tenantIdcome from the session, never from the request body. - Use an allow list of writable fields on PATCH, so
roleis rejected. - Review what
expand=settingsreturns for each role.
Keeping hidden parameters from reappearing
Generate the OpenAPI spec from code and compare it to the previous version in each pull request. A new field on a request or response appears as a diff. Any field that is not in the public docs but is accepted by the server should be justified or removed. Add a test that sends unknown fields to each write route and expects them to be rejected or ignored, never stored.
Why clues beat guessing
Wordlist guessing against a production API is noisy, slow and can trip the flooding rules cloud providers publish. Clues from traffic, code and old specs are quieter and find the parameters that actually exist.
Try it yourself
Open the demo and look at how findings reference the request that caused them. For hidden parameters, that request is the evidence, so keep the exact request and response for each probe.
Click through it at your own pace, or open it full screen.
Quick check
Is a hidden parameter a vulnerability by itself?
Not by itself. It becomes one when it changes behavior without proper authorization, for example granting a role or revealing data.
Should I brute force parameter names against production?
Avoid it. High-volume guessing can look like flooding, which cloud testing policies prohibit. Use captured traffic, code and docs first, and test names in a test environment.
Do hidden parameters always mean the API was built carelessly?
No. They often start as helpers for admin screens or old clients. The risk comes from forgetting them. Treat every accepted parameter as part of the API surface and review it.
Sources
Last reviewed: 19 October 2026.