← All posts
JavaScriptAPI securityAttack surface

JavaScript is your hidden attack surface

prayersec team · · 4 min read

Open any modern web app, press F12, and look at the JavaScript it downloads. Somewhere in those bundles is a list of every API route the app can call, the admin screens it can render, the internal hostnames it talks to and, too often, a key that should never have left the server. Attackers read it. Most security programs don't.

Your frontend is a map of your backend

Single-page apps built with React, Vue, Angular, Nuxt or Next do their work in the browser. To do that, the browser has to be told where everything is. So the code you ship contains:

  • API routes, often all of them, including ones the current user's role never calls: /api/v1/admin/users, /api/auth/impersonate, /api/export/all.
  • Page routes for screens the user can't see yet. Admin and internal pages are usually just another lazily loaded chunk, and that chunk downloads for anyone who asks for it.
  • Hostnames and base URLs for staging servers, internal services, storage buckets and third-party APIs.
  • Secrets that slipped through: API keys, tokens and connection strings that a build step baked in.
  • Source maps that hand over the original, readable source code, comments and all.

Minification doesn't hide any of this. It shortens variable names, but the strings an app needs to work (URLs, paths, parameter names) survive untouched. Reading them back out is a well-known recon step, and free tools have done it for years.

Why it stays hidden from defenders

Each of the usual tools looks at the app from an angle that misses the JavaScript:

  • API inventories list what is documented in an OpenAPI spec or seen in traffic. A route that exists in the code but that nobody has called yet isn't in either.
  • DAST scanners click through the pages they can reach. They rarely reach the admin chunk, and they treat the bundle as a file, not as a list of targets.
  • Attack surface tools see hosts, ports and certificates. They stop at the front door and never read what the site tells the browser.
  • The WAF protects requests that pass through it. If the origin server also answers directly, everything the JavaScript reveals can be called around the WAF.

Meanwhile, the code changes with every release. The inventory someone built for last quarter's pentest is already out of date.

What an attacker does with it

  1. Download every script the site loads, including lazily loaded chunks and any published source maps.
  2. Pull out the routes, parameters and hosts.
  3. Call the interesting ones without signing in, or with a low-privilege account, and see what answers.
  4. Look for the origin server behind the CDN and send the same requests there, past the WAF.

None of this needs an exploit. It needs an hour and an app that trusts the frontend to hide things.

How prayersec solves it

JS Mapper does the same reading an attacker would, for the people who own the app, and turns it into something a security team can act on.

  1. Prove ownership first. Nothing is scanned until you verify the domain with a DNS record or a file. We only ever look at your own apps.
  2. Collect everything the browser would. We crawl the app (signed in, if you add a session), download every script including lazy chunks, and recover original source from published source maps.
  3. Read it two ways. Pattern matching catches the obvious strings. AI then reads each piece of code the way a developer would: it follows constants, base URLs and client wrappers like axios instances, and records the method, parameters and how each call is authenticated. The AI runs on models we host ourselves, so your code is never sent to a third-party AI service.
  4. Check the AI's work. Every endpoint is checked against the code it came from. Ones whose path is in the code are marked as found in the code; anything AI suggested that isn't there is flagged as a lead, never presented as fact.
  5. Test what's safe to test. Endpoint checks send plain GET requests with no credentials, skipping anything that takes an ID or sounds like it changes data. AI then judges each response: public, internal, or sensitive data exposed to anyone.
  6. Compare the edge with the origin. If your WAF blocks an endpoint but an exposed origin server answers it anyway, you get a high-severity finding with both responses as evidence. This is the finding we don't know of another tool that produces.
  7. Keep up with releases. Re-map on every sprint or on a schedule, and get alerted when new endpoints, secrets or source maps appear. Export the map to OpenAPI, Postman, Burp or ZAP for your testers.

A checklist you can use today

  • Don't publish source maps to production, or protect them behind authentication.
  • Never put secrets in frontend code or build-time environment variables that end up in the bundle.
  • Authorize every API call on the server. Hiding a button is not access control.
  • Don't ship admin features to everyone: split them into a separate app or require auth to load them.
  • Lock your origin so it only accepts traffic from your CDN or WAF.
  • Re-inventory your API surface on every release, not once a year.

If you'd like to see what your own JavaScript says about you, map one app free. It takes a few minutes, and the first results usually start a conversation.

Share LinkedIn X

See what your JavaScript says about you

Verify a domain and map one app free. It takes a few minutes.

Start free