API Endpoint Discovery Through JavaScript Bundle Analysis

Pentester's guide to extracting API routes from frontend code before authentication begins.

· 8 min read
Cover illustration for “API Endpoint Discovery Through JavaScript Bundle Analysis”
Recon and Enumeration · October 17, 2026 · 8 min read · 1,854 words

JavaScript bundle analysis turns the code a modern SPA sends to visitors into a map of its API surface. That exposure is part of the architecture. A thorough penetration test must extract the map, test its access controls, and connect findings into proven attack paths.

Why every SPA visitor already has a map of the application's API surface

A React or Vue SPA sends the browser hundreds of kilobytes of minified JavaScript assembled from hundreds of source files. That code contains the routes, API URLs, authentication logic, and data models the frontend needs to work. The browser must know where to send requests before it can use the application. As a result, an unauthenticated visitor loading a login page can receive as much API surface information as an authenticated user exploring every feature. Hiding a feature in the interface does not hide its address in the code.

When Next.js and Vite build the code, they replace environment variables marked as explicitly public with literal values. The NEXT_PUBLIC_ and VITE_ prefixes mark values for publication in the client bundle. Variables without those prefixes are not exposed through that substitution mechanism. What the frontend knows is public, but the server still has to decide what each caller may do.

What a JavaScript bundle actually contains and why static code scanning misses most of it

The useful material extends well beyond URL strings. Bundles can contain internal service hostnames, GraphQL schemas, WebSocket endpoints, authentication logic, and sometimes hardcoded credentials. Those credentials range from AWS access keys and repository tokens to database connection strings. Data models show which fields an API accepts or returns.

Source-code scanning does not necessarily inspect what visitors ultimately receive. A credential introduced during the build can materialize in the production bundle after static application security testing has finished. The static scanners that were tested found only a fraction of live credentials, while manual analysis found things that all of those scanners missed. The gap is therefore not just a matter of choosing a better search pattern. It also concerns when the code is inspected and which resources are included.

Encrypted configuration makes that limitation concrete. CryptoJS-encrypted configuration defeated every static scanner in the cited research because the credential appeared only after decryption with a key stored nearby. Runtime-aware detection could find what static inspection missed. Third-party resource inclusions create another blind spot when analysis stops at the primary bundle. Encryption and indirection can make a scanner fail to recognize a client-side secret.

How to extract API endpoints from a bundle before the page even finishes loading

Raxis’s enumeration walkthrough starts with the browser’s own developer tools. Open DevTools before navigating to the target and set a debugger breakpoint on beforeunload or load. Pausing around navigation can keep a redirect-heavy SPA from carrying the browser away before its scripts are inspected. The Sources tree shows files that have already loaded, including bundled chunks and loaded lazy modules, along with any source maps that are available. Files can then be saved locally with Save As, or the folder structure can be saved for a larger application.

Once the files are local, simple searches provide a useful first pass. Patterns such as /api/, fetch(, axios., and .get( expose common request syntax in smaller bundles. Minification makes code harder to read, but frameworks still leave recognizable fingerprints. Exposed source maps amplify this method by allowing reconstruction of the pre-minification source.

Not every browser application ships its logic as JavaScript. Blazor WebAssembly applications ship compiled.NET assemblies as DLLs, which standard JavaScript tooling skips. The manifest at _framework/blazor.boot.json lists the loaded assemblies and their hashes. ILSpy or ilspycmd can decompile those assemblies into readable C#, where searches for HttpClient, GetFromJsonAsync, PostAsJsonAsync, [Route, and /api/ reveal request paths. Classes named AdminService or InternalApiClient should be among the first chosen for object-level authorization testing.

For large or heavily minified bundles, a local language model such as Llama or Qwen can help extract endpoints, methods, parameters, and administrative-looking paths. Frontier models are an option only when the engagement contract explicitly permits their use and an enterprise account excludes prompts from training data. Sending a client’s source code to a free-tier consumer model leaks that code.

Specialized tools that go deeper than grep — LinkFinder, JS Miner, Katana, and gau

LinkFinder parses minified JavaScript with regular expressions to extract paths. Filtering its output for api, v[0-9], graphql, and rest helps pick out what may be API references. That produces a map from the code available now, but current code is only part of the picture. Older addresses may still point to services that work.

gau, or GetAllURLs, adds that historical view by pulling URLs from the Wayback Machine and Common Crawl. Its results can expose deprecated API versions that remain live and may be less hardened than their replacements. JS Miner then adds passive scanning during browsing, covering GET, POST, PUT, DELETE, and PATCH methods. It also uses Shannon entropy analysis to look for hardcoded secrets and reconstructs source from exposed JavaScript source maps. These approaches complement static extraction.

JavaScript rendering completes the progression from stored code to dynamically presented content in a toolkit that includes a web crawler. Even so, tool coverage is not the same as assessment coverage. Comparing staging and production bundles can reveal routes removed from the production interface but never decommissioned on the production API server. Such differences identify candidates that a crawl of the visible application can miss. The important distinction is between an endpoint that disappeared from the UI and one that stopped accepting requests.

What the extracted endpoint map reveals — the vulnerability classes that live inside bundles

An extracted endpoint is a lead. Hardcoded credentials become meaningful findings when testing establishes that they are active and what access they grant. A Stripe key, for example, should be tested against the Stripe API before being reported as a valid secret. Research found active GitHub and GitLab tokens granting full repository access, showing why this validation matters. A string that looks sensitive and a credential that opens a repository are very different findings.

Internal addresses can expose a more direct failure in the authentication boundary. In one documented case, an API Gateway correctly enforced authentication, but the Lambda function behind it was independently addressable without authentication of its own. Calling the Lambda URL directly bypassed the gateway’s protection. Bundle analysis supplied the route around the control. A standard crawl of authenticated user flows would not expose that separate entry point.

Endpoint paths and data models also reveal where to test authorization. For Broken Object Level Authorization, or BOLA/IDOR, the bundle supplies endpoints and identifier parameters that can be changed to test whether the server enforces ownership. OWASP API Security lists BOLA as the top API risk. Embedded admin routes point to a related test for Broken Function Level Authorization, namely whether a lower-privileged caller can invoke a privileged handler. A hidden admin panel does not establish that its API functions are protected.

Data models show what to try in mass-assignment tests when a server copies the whole request body onto a user object without allowlisting fields. Extra fields that set role to "admin" or verified to true can then alter privileges the caller should not control. GraphQL query structures and partial schemas provide another form of disclosure. If server-side introspection is also enabled, its response and the bundle can expose the available types and fields. In each case, the code narrows the test to a specific server-side assumption.

How attack chains are built by combining bundle findings

A tenant ID exposed by a user profile endpoint can become the missing input for an IDOR on a records endpoint. Together, those weaknesses can let a caller access data across tenants, even when neither finding is critical on its own. The same logic applies to an internal API hostname combined with an unauthenticated endpoint on that service. The bundle supplies the address, and the unprotected endpoint supplies the entry.

A fintech lender engagement documented in 2026 illustrates the difference that fuller enumeration and grey-box access can make. Three findings missed by the prior black-box test were found within two days once endpoint enumeration was complete. The available account does not specify those three findings, so it cannot support a more detailed reconstruction of the chain. It does, however, show why the endpoint inventory and the access available to testers affect the result. Reporting discovered URLs as informational and stopping there leaves their security consequences unanswered.

Tests must show whether the access, information, or capability gained at one step makes the next step possible. Following the sequence also exposes the limits of the testing method, because some ownership and privilege checks require authenticated access.

How testing methodology — black box, grey box, and white box — changes what bundle analysis can find

Bundle analysis is inherently black box because it starts with code any visitor can receive. It can reveal secrets, shadow APIs, and exposed endpoints without privileged access. But a map of endpoints alone cannot show whether authenticated business logic or ownership checks work as they should. To test those checks, testers need access to the user context in which they run.

Grey box is the recommended starting point for multi-tenant SaaS because it combines the map with credentials needed to test IDOR and tenant isolation. The fintech engagement illustrates what this adds to prior black-box work. White box takes the work into the code, where endpoints found in the bundle guide authentication-bypass review and root-cause analysis. Most SaaS teams that want both compliance coverage and a way to find real threats use grey box with white box. One tests the application’s behavior, while the other examines the structures that produced it.

What a thorough pen test of a modern SPA's API surface actually requires

A standard proxy crawl follows the application paths a tester happens to use. That leaves gaps around admin paths, legacy versions, internal tooling, mobile-only routes, and feature-flagged previews behind the same API host. To cover those gaps, testers must extract bundles across application states, including pre-redirect scripts and lazy-loaded modules. Historical URL enumeration and staging-to-production comparison extend that inventory beyond the current interface. Only then is there a sound basis for testing access controls across the discovered surface.

The assessment must turn that coverage into evidence. Credential hits need live API validation, and endpoints need testing in combination to establish multi-step exploit paths. Whitebox access to source code, cloud configurations, and product documentation helps follow frontend calls through backend logic and confirm root causes. Human experts who review the results bring judgment that automated extraction cannot supply. Findings presented as SOC 2, HIPAA, or ISO 27001 compliance evidence must be supported by working exploits.

A point-in-time test also needs a complement in the delivery pipeline. Continuous pull-request scanning that covers build output can catch secrets and endpoint changes at their point of introduction, before an annual assessment. Alongside runtime-aware analysis and manual review of production artifacts, it addresses the same architectural fact from another direction. The frontend must publish what it needs to call, so rigorous testing must establish what those calls actually allow.

More in Recon and Enumeration