Information Disclosure in APIs: How I Find Data Leaks Before Attackers Do

Information Disclosure in APIs: How I Find Data Leaks Before Attackers Do

Information disclosure is one of the quietest categories of API vulnerabilities, and that’s exactly what makes it dangerous. There’s no dramatic exploit, no crash, no obvious error — just an API that tells you a little more than it should. Over time, testing APIs, I’ve learned that these small leaks add up fast, and they’re often the first domino in a much bigger attack chain. In this article, I’ll walk through every place I look for information disclosure when testing an API.

What Counts as Information Disclosure?

Information disclosure happens whenever an API reveals data that the requesting party shouldn’t have access to. This can range from something as small as a software version number to something as serious as another user’s private data or internal system credentials. I split it into a few broad categories:

  1. Technical disclosure — server versions, stack traces, internal file paths, framework details
  2. Business logic disclosure — internal pricing logic, unpublished features, admin-only functionality hints
  3. User data disclosure — personal information belonging to other users
  4. Credential and secret disclosure — API keys, tokens, internal service URLs

Step 1: Testing Error Messages

This is the first place I look, because it’s the easiest place for developers to slip up. I intentionally send malformed requests to see what comes back:

I’m looking for responses that include:

{
  "error": "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'app_prod.users_backup' doesn't exist",
  "trace": "at UserController.php:142"
}

A response like this tells me the database type, table naming conventions, the framework, and even the file path of the code handling the request. That’s a lot of free reconnaissance handed over by a single bad request.

Step 2: Testing HTTP Response Headers

Headers are an underrated source of information disclosure. I always check for:

Server: Apache/2.4.41 (Ubuntu)
X-Powered-By: PHP/7.2.24
X-AspNet-Version: 4.0.30319

These headers tell me exact software versions, which I can then cross-reference against known CVEs. I also check for internal debugging headers accidentally left enabled in production, like X-Debug-Token (common in Symfony apps) which can sometimes link to an exposed debug panel.

Step 3: Testing for Verbose API Responses (Excessive Data in Legitimate Fields)

Sometimes the disclosure isn’t in an error — it’s baked right into a normal, successful response. I check whether an endpoint returns more fields than the frontend actually displays. For example, a /api/users/123 endpoint might return:

{
  "id": 123,
  "name": "Jane Doe",
  "email": "jane@example.com",
  "passwordHash": "$2b$10$...",
  "internalNotes": "Flagged for chargeback dispute",
  "ssn_last4": "1234"
}

Even if the frontend only displays the name, the raw API response might be leaking password hashes, internal notes, or partial sensitive identifiers to anyone who inspects network traffic. I always check the full raw JSON response, not just what’s rendered on screen.

Step 4: Testing for User Enumeration

I test whether an API’s responses let me determine if a specific username, email, or account ID exists, even without full access to that account. Common places this shows up:

Step 5: Testing for Directory and Endpoint Disclosure

I look for ways the API accidentally reveals its own structure:

Step 6: Testing for Metadata and Comment Leakage

I check API responses (and any accompanying static files) for:

Step 7: Testing for Cross-User Data Leakage in List Endpoints

I pay close attention to any endpoint returning a list of items — search results, activity feeds, recommendation engines — because these often leak more than single-object endpoints. I test:

Step 8: Testing Third-Party Integrations for Leakage

APIs often pull in data from third-party services (payment processors, analytics, CRM tools). I test whether:

Step 9: Testing Cached Responses

I check whether sensitive, user-specific API responses are being cached by CDNs or reverse proxies without proper cache-control headers, which could let one user’s cached response be served to another user requesting the same URL.

Cache-Control: private, no-store

If this header is missing on a personalized endpoint, I test by making requests from two different sessions and seeing if a shared cache layer serves stale, cross-user data.

Tools I Use for Information Disclosure Testing

Common Information Disclosure Issues I Keep Finding

  1. Verbose error messages leaking stack traces and database structure.
  2. API responses including internal fields never meant for the client (password hashes, internal flags, admin notes).
  3. Login/registration flows confirming whether an email or username exists.
  4. Swagger/OpenAPI documentation exposed publicly, revealing undocumented endpoints.
  5. Source maps deployed to production, exposing readable source code.
  6. Missing cache-control headers on personalized API responses.

How I Recommend Fixing Information Disclosure Issues

Final Thoughts

Information disclosure rarely feels like “the big vulnerability” on its own, but I’ve used disclosed information time and again as the starting point for much more serious attacks — confirming valid usernames before a credential stuffing attempt, or using a leaked stack trace to pinpoint the exact framework version to target. Treat every piece of information an API reveals as a potential building block for a bigger attack, because that’s exactly how it gets used.

Exit mobile version