/ Case Study

Uncovering Government Crown Jewels in 12 Minutes

How Korrosiv.AI turned a dead endpoint into a full kill chain - pivoting through JavaScript bundles, metrics endpoints, and internal APIs to uncover a critical data exposure on a government platform.

Disclosure: This vulnerability was responsibly disclosed and has been remediated by the vendor. All identifying details, endpoint paths, parameter names, and personal data have been redacted or generalised. The methodology and reasoning chain are presented accurately.
TL;DR: Korrosiv.AI was pointed at a single endpoint that returned 404. Starting from nothing, it autonomously reverse-engineered a React JavaScript bundle to map 9 backend microservices, found unauthenticated metrics endpoints leaking every API route, and chained the information into an unauthenticated IDOR exposing ~72,000 citizen records with full PII. Total time: 12 minutes.

The Setup

The target was a government services platform serving tens of thousands of citizens. It ran a modern React single-page application backed by multiple microservice APIs. Korrosiv.AI was assigned a specific endpoint to test for WAF and bot protection controls.

That endpoint returned a 404. It didn't exist.

A human pentester, pressed for time, would likely have logged the result and moved on. Korrosiv.AI treated it as a starting point.

Phase 1: Mapping the Backend Through the Frontend

With the assigned endpoint dead, Korrosiv.AI pivoted to understanding what was running on the domain. It navigated to the application root and found the React SPA shell, which loaded a 2MB JavaScript bundle.

Korrosiv.AI downloaded and analysed the bundle, extracting every hardcoded URL. This revealed nine backend microservices - each handling a different domain of the platform's functionality: authentication, identity management, case processing, form handling, and several others.

Critically, the bundle also contained route patterns referencing internal administration paths - debugger interfaces, maintenance pages, and user impersonation endpoints. Routes that should never have been compiled into production JavaScript.

Key insight: Modern SPAs often compile their entire route structure into the JavaScript bundle, including routes intended for internal use. This gives an attacker a map of the application's full functionality - not just what's visible in the UI.

Phase 2: The Metrics Goldmine

Korrosiv.AI tested each of the nine discovered services for common management endpoints. It found that every single service had its application metrics endpoint publicly accessible with zero authentication.

These weren't small responses. The metrics payloads ranged from 400KB to over 1MB per service - and they contained something invaluable: every URI the services had ever handled, recorded as HTTP request metrics.

Metrics response (redacted)
# Exposed across all 9 services - no authentication

Service 1 (identity)  ........  508 KB
Service 2 (auth)  ............  611 KB
Service 3 (forms)  ...........  573 KB
Service 4 (case mgmt)  .......  944 KB
Service 5 (dashboard)  .......  1.08 MB
Service 6 (records)  .........  570 KB
Service 7 (processing)  ......  476 KB
Service 8 (compliance)  ......  442 KB
Service 9 (verification)  ....  367 KB

This is the equivalent of handing an attacker a complete map of every API endpoint in your platform, organised by service. Korrosiv.AI extracted route patterns from the identity service's metrics that referenced internal API paths with user lookup capabilities.

The metrics also leaked database connection pool configurations, JVM thread counts, and JDBC connection details - infrastructure information that should never be exposed externally.

Phase 3: Internal Endpoints on the Public Internet

Korrosiv.AI confirmed that internal administration paths were not only compiled into the frontend JavaScript - they were fully accessible from the public internet.

Status and health check endpoints on every service returned detailed infrastructure information without any authentication:

Internal status endpoint - publicly accessible
{
  "version": "6.xx.x-CR-XXXXXXX.x",
  "gitCommit": "XXXXXXX",
  "branch": "release/CR-XXXXXXX",
  "statusItems": [
    { "item": "External API connection", "result": true },
    { "item": "Address verification server", "result": true },
    { "item": "LDAP directory", "result": true },
    { "item": "Identity verification service", "result": true }
  ]
}

Version numbers, git commit hashes, branch names, database connection states, LDAP availability, and third-party service integrations - all exposed to anyone who knew where to look. And now Korrosiv.AI knew exactly where to look.

Phase 4: The Critical IDOR

Among the routes extracted from the identity service metrics, one stood out - an internal authorisation lookup endpoint. Korrosiv.AI sent a request with no parameters:

Error response reveals parameter requirements
HTTP 400 Bad Request

"Required request parameter '████████' for method
 parameter type Long is not present"

The error message handed over the exact parameter name and its expected data type. Korrosiv.AI supplied a value of 1.

The response came back HTTP 200. No authentication required. The full record of the first user in the database:

HTTP 200 - zero authentication
{
  "accountCreatedDateTime": "20XX-XX-XX XX:XX:XX",
  "accountId": 1,
  "userName": "████████@████████.com",
  "email": "████████@████████.com",
  "fullName": "████████, ████████",
  "surname": "████████",
  "givenNames": "████████",
  "admin": false,
  "party": {
    "type": "individualParty",
    "partyId": XXXXXX,
    "identityVerified": false,
    "userId": XXXXX
  },
  "partyAuthorisations": [...]
}

Full name. Email address. Account creation date. Internal party and user identifiers. Admin status. Identity verification flags. Employer information. Complete authorization permissions. All returned for any sequential ID value, with no authentication whatsoever.

Phase 5: Confirming the Blast Radius

Korrosiv.AI needed to understand how many records were exposed. Rather than enumerate every ID (which would have been irresponsible), it used a binary search - testing exponentially increasing values to find the boundary where valid records stopped.

Binary search enumeration
ID = 100      valid record (3.5 KB)
ID = 5,000    valid record
ID = 10,000   valid record
ID = 25,000   valid record (with employer data, 7 authorisations)
ID = 50,000   valid record (6.6 KB)
ID = 60,000   valid record
ID = 65,000   valid record
ID = 70,000   valid record
ID = 72,000   valid record (3.5 KB)
ID = 73,000   error page (26 KB)
ID = 74,000   error
ID = 75,000   error

The boundary sat between 72,000 and 72,050. Approximately 72,000 user accounts with complete personally identifiable information, accessible to anyone on the internet with a sequential integer.

The Kill Chain

The full attack path, from dead endpoint to critical data exposure:

1
Dead end

Assigned endpoint returns 404

2
Pivot to recon

Download and analyse the React SPA's 2MB JavaScript bundle

3
Service discovery

Extract 9 backend microservice URLs and internal route patterns from the bundle

4
Route mapping

Hit exposed metrics endpoints on all 9 services - extract every API route ever served

5
Parameter discovery

Trigger a verbose error that reveals the exact parameter name and type

6
Critical IDOR

~72,000 user records with full PII, zero authentication, sequential integer IDs

Total time from first request to confirmed critical finding: approximately 12 minutes.

What Makes This an AI-Native Finding

No individual step in this chain is novel. JavaScript analysis, metrics endpoint enumeration, IDOR testing - these are all well-known techniques. What makes this finding distinctly AI-native is the chain of reasoning that connected them:

  1. Autonomous pivoting. Korrosiv.AI wasn't told to analyse JavaScript bundles or test metrics endpoints. It decided to do so when its assigned target returned 404 - adapting its strategy in real time based on what it observed.
  2. Cross-domain correlation. Korrosiv.AI connected information from the frontend JavaScript (service URLs), application metrics (route patterns), error messages (parameter names), and API responses (data schema) across four different sources to build the attack path.
  3. Responsible scoping. When confirming the blast radius, Korrosiv.AI used binary search rather than linear enumeration - testing 12 IDs instead of 72,000 to establish the scope without unnecessarily accessing user data.
  4. Contextual understanding. Korrosiv.AI recognised that "internal" route patterns in a production JavaScript bundle were a significant finding on their own, and that publicly accessible metrics endpoints would contain route information - reasoning that requires understanding how modern microservice architectures are deployed.

A human pentester under typical engagement time pressure would be unlikely to make the connection between a JavaScript bundle, metrics endpoints, and an internal API. They would have tested the assigned endpoint, logged the 404, and moved on to other targets. The vulnerability would have remained undiscovered.

The Broader Lesson

This vulnerability existed because of a common architectural assumption: that internal endpoints are safe because they're "internal." But in a microservice architecture exposed through a shared API gateway, the boundary between internal and external is a configuration detail, not a network guarantee.

The metrics endpoints provided the roadmap. The JavaScript bundle provided the service map. The verbose error messages provided the parameter names. And the internal API provided the data - all without a single authentication check.

These aren't exotic attack techniques. They're the natural consequence of following a thread - observing, reasoning, and pivoting - the way a skilled pentester would. The difference is that Korrosiv.AI does it in 12 minutes, every time, at scale.

This finding was discovered by Korrosiv.AI during development testing and responsibly disclosed to the vendor. Read more about AI-native penetration testing or view our full track record.