Use static analysis alongside browser-based crawling. Dynamic crawling with a headless browser finds what the app renders at runtime, but static analysis can inspect code paths that never execute in a crawl session. The best approach is to extract URLs, paths, methods, and request shapes from source, then probe the resulting surface for access control issues, hidden functionality, and secrets exposure.
Why static analysis and browser crawling need to work together
JavaScript-heavy applications often hide real attack surface behind runtime rendering, lazy-loaded modules, feature flags, and API calls that never appear in the first HTML response. A browser-based crawler is necessary to execute those paths, but it only sees what the current session can reach. Static analysis fills the gap by extracting endpoints, methods, and request shapes from code that a crawl may never trigger.
The practical goal is coverage, not just traversal. If you rely on rendered pages alone, you will miss routes that are gated behind user actions, conditional logic, or client-side branching. If you rely on source alone, you can over-collect dead code and stale references. The useful result is a reconciled inventory of live endpoints that includes both observed behavior and code-discovered surface.
That matters because hidden API calls are often where authorization mistakes, excessive exposure, and sensitive data leakage show up first. A crawler that can execute a full browser session and a static pass that can extract unvisited request paths gives you a much better chance of finding the real trust boundary, not just the visible UI.
What to extract from source before you probe
The highest-value static targets are URLs, route templates, HTTP methods, query parameters, JSON field names, and client-side request builders. Those details let you infer not only where requests go, but also which operations may exist even when no link or button exposes them. Look for fetch wrappers, GraphQL operations, WebSocket connections, mobile-style API client helpers, and obfuscated string assembly that may hide endpoints.
Then normalize what you find into a candidate surface for active testing. Deduplicate repeated paths, preserve parameter patterns, and separate clearly documented routes from inferred ones. That distinction helps avoid noisy probing while still exposing functionality that is intentionally hidden from casual navigation.
One useful discipline is to treat static findings as hypotheses, not truths. A client-side reference to an endpoint does not guarantee that the route is deployed, reachable, or safe. Probing should confirm reachability, auth requirements, and response shape before you infer business impact or report a finding.
How to turn the expanded surface into better security coverage
Once you have the merged surface, prioritize checks for access control, method confusion, and secret exposure. Hidden endpoints often bypass normal UX guardrails, so they deserve the same validation as public routes. If a route only appears in source, verify whether it still enforces authentication, whether it leaks implementation details, and whether it exposes functions that the UI never intended to reveal.
The same workflow also improves secret discovery. JavaScript bundles, source maps, configuration blobs, and build artifacts can expose API keys, tokens, backend hostnames, and environment hints. Static analysis should therefore be paired with secret scanning and endpoint discovery, because the two problems usually overlap in client-heavy applications.
For a broader api security lens, the OWASP API Security Top 10 is the right external reference for the kinds of authorization and exposure failures this workflow is meant to uncover. In practice, the crawl is only the first step, and the real value comes from validating what those endpoints allow, not just whether they exist.
Risk and Threat Considerations
JavaScript-heavy apps increase the chance that important functionality exists outside the obvious navigation path. That creates two risks: defenders miss sensitive endpoints during testing, and attackers discover undocumented operations that were never meant to be user-facing. Hidden routes are especially dangerous when they inherit weak authorization or return data the UI would normally suppress.
Failure mechanism: client-side code reveals or invokes endpoints that are not reachable through ordinary browsing, then a crawler or tester misses them if it only follows rendered links and visible actions. The result is incomplete coverage of access control, input handling, and secret-bearing request paths.
Impact: unaudited endpoints can leak secrets, expose business logic, or permit unauthorized actions through direct API calls. In the worst case, the visible interface looks safe while the underlying application surface still contains exploitable functions.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP API Security Top 10 provides the primary governance reference for this topic.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP API Security Top 10 | API5 — Broken Function Level Authorization | Hidden endpoints must be checked for unauthorized access to functionality. |
| API8 — Security Misconfiguration | Client-heavy apps often expose undocumented routes and unsafe surface through misconfiguration. | |
| API2 — Broken Authentication | Crawled API calls still need auth validation when hidden from the UI. | |
| Recommendation — Test discovered routes for function-level authorization before trusting client-side visibility. Audit discovered endpoints for misconfiguration and unexpected exposure. Verify that runtime-discovered endpoints enforce authentication consistently. | ||
Practitioner Guidance
What to verify: make sure your crawl stack can execute the same JavaScript branch patterns that real users trigger, then compare that result with a source-derived endpoint list. If the static list is much larger than the browser-discovered set, treat the difference as a review queue, not as noise to discard.
What good looks like: you can explain, for each discovered route, whether it was observed at runtime, inferred from source, or confirmed by an explicit request trace. That provenance makes it much easier to prioritize authorization testing and decide which “hidden” endpoints are truly security relevant.
Practitioner takeaway: the most reliable workflow is not “crawl harder,” but “crawl and read the code together,” because JavaScript-heavy apps often reveal their most important attack surface only when runtime behavior and source inspection are combined.
Related resources from NHI Mgmt Group
- How should security teams modernise SAML-based web apps for API-first architectures?
- How should security teams test large applications and APIs without missing hidden risk?
- How should security teams implement API-based CASB for SaaS and cloud apps without disrupting users?
- How should security teams implement DLP across cloud apps, endpoints, and AI tools without blocking normal work?
Deepen Your Knowledge
Reviewed and updated by the NHIMG editorial team on September 29, 2026.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org