Safeguard
Security Guides•

How do you find and test hidden API parameters?

Hidden parameters appear in traffic, client code and older specs. Capture requests across roles, probe with invalid values and watch how responses differ.

Safeguard Security Team
7 min read

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

  1. Send the normal request and save the response as a baseline.
  2. Add the parameter with a clearly invalid value, such as an absurdly long string or a wrong type.
  3. 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.
  4. Try a harmless valid value and look for a difference in the response body, fields or order.
  5. 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.
  6. Try it on older API versions and alternate hosts.

Parameters that deserve special care

KindWhy it mattersWhat to check
Role or permission fieldsMass assignment can promote an accountWhether the server accepts and stores them
Tenant or owner IDsCan cross isolation boundariesWhether the server trusts them over the session
Debug or verbose flagsCan leak internal detailWhether they work outside development
Filter and include optionsCan widen the data returnedWhether the same authorization applies
Pagination limitsCan pull huge data setsWhether 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=settings when 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 a tenantId field in a request builder.
  • An older OpenAPI file, still reachable on a staging host, lists a role field 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.

SuspectTestObservationMeaning
expand=settings, as regular userAdd to GETResponse includes a settings object with notification optionsWorks for a regular user too. Probably fine, but check whether it includes anything sensitive
debug=trueAdd to GETResponse gains a debugInfo block with a SQL query and server nameDebug output reachable in staging, must not exist in production
tenantId in PATCH bodySend another tenant's IDServer returns 200 and the next GET shows the other tenant's profile dataTrusts a client-supplied tenant. Serious
role in PATCH bodySend "role": "admin"200, and the next GET shows role adminMass 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 debug outside development builds.
  • Make tenantId come from the session, never from the request body.
  • Use an allow list of writable fields on PATCH, so role is rejected.
  • Review what expand=settings returns 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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.