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.
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.
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.
# 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:
{
"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:
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:
{
"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.
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:
Assigned endpoint returns 404
Download and analyse the React SPA's 2MB JavaScript bundle
Extract 9 backend microservice URLs and internal route patterns from the bundle
Hit exposed metrics endpoints on all 9 services - extract every API route ever served
Trigger a verbose error that reveals the exact parameter name and type
~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:
- 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.
- 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.
- 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.
- 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.