Skip to content

About

Ethical static analyzer that maps a web app's own JS bundle - endpoints, routes, leaked secrets - for authorized self-audit (Node CLI).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

web-surface-mapper

Map a web application's own JavaScript bundle to the API/route "surface" it exposes: HTTP endpoints, route paths, base URLs, notable config keys, and patterns that look like accidentally-bundled secrets.

It is a small, dependency-light static analyzer and a compact reverse-engineering / recon utility from my security-review toolkit. It answers one defensive question: "What is my web app unintentionally revealing to anyone who opens DevTools?"


Ethical use (read this first)

This tool is for authorized self-audit only. Run it on:

  • your own applications (your code, your bundles), or
  • targets you are explicitly authorized to test — a signed penetration-test engagement, or assets that are in scope for a bug-bounty program.

It is a defensive awareness tool. Everything a browser downloads to run your app is already readable by every visitor; this tool just makes what you ship easy to review before an attacker does it for you.

What it will never do: it does not attack, exploit, log in, fuzz, or call any endpoint it discovers. It does not transmit, upload, or exfiltrate anything. It only reads the JavaScript you point it at and prints findings to your terminal. Flagged secrets are redacted by default so the report itself is safe to share with a teammate.

If a target is not yours and not in a documented authorization scope, do not point this (or any other recon tool) at it.


What it does

Given a JavaScript file (typically a built/minified front-end bundle), it statically reports:

  • API endpoints — fetch(), axios (axios(...), axios.get/post/..., axios.create), XMLHttpRequest.open(), and jQuery $.ajax, each with its HTTP method and URL. Template/computed URLs are kept and marked [dynamic].
  • Route / path literals — string literals that look like routes (e.g. /api/users, /admin/users, /settings/billing).
  • Base / absolute URLs — https://… origins and baseURL values.
  • Notable config keys — apiKey, baseURL, clientId, apiVersion, graphqlUrl, etc.
  • Potential secrets — high-signal patterns (JWTs, AWS/Google keys, Stripe keys, GitHub/Slack tokens, private-key blocks, Bearer literals) and credential-like assignments (apiKey: "…"), flagged for you to review.

Output is a structured JSON report plus a clean human-readable summary.

It uses acorn to parse the bundle into an AST for accurate method/URL extraction. If acorn is not installed, it automatically falls back to a regex pass (labeled in the report) so it still runs with zero dependencies.


Install & run

Requires Node.js 18+ (developed and tested on Node 24).

git clone <your-fork-url> web-surface-mapper
cd web-surface-mapper
npm install          # installs acorn (optional but recommended)

# analyze a local bundle
node bin/cli.js path/to/app.bundle.js
# or, after `npm link` / global install:
web-surface-mapper path/to/app.bundle.js
# or without installing:
npx . path/to/app.bundle.js

# run the built-in sample
npm run demo

Options

web-surface-mapper <path-to-js-file> [options]
web-surface-mapper <https://url-to-bundle.js> [options]   (authorized targets only)

  --json            Print the structured JSON report to stdout
  --out <file>      Write the JSON report to <file>
  --show-secrets    Reveal full flagged values locally (default: redacted)
  --no-color        Disable colored output
  -h, --help        Show this help

Passing an https:// URL downloads that script once (a plain GET, like curl) and analyzes it locally — use it only on bundles you are authorized to fetch and test. Nothing about you or your systems is sent.


Sample output

The repo ships a synthetic bundle at sample/app.bundle.js containing fake endpoints, routes, and obviously-fake tokens (reserved .example domains, placeholders like EXAMPLE_fake_key_do_not_use). Running npm run demo produces:

Web Surface Mapper  —  authorized self-audit only
Source:  sample/app.bundle.js
Scanned: 2026-10-13T23:07:59.619Z  ·  parser: acorn-ast

API ENDPOINTS (7)
  POST    /api/orders [http-client] (line 16)
  DELETE  /api/orders/42 [axios] (line 17)
  GET     /api/products [http-client] (line 15)
  PUT     /api/profile [xhr] (line 18)
  GET     /api/users [fetch] (line 13)
  POST    /api/users [fetch] (line 14)
  GET     /api/users/${userId}/posts [dynamic] [fetch] (line 19)

ROUTE / PATH LITERALS (10)
  /admin/users (line 21)
  /api/orders [api] (line 16)
  /api/orders/42 [api] (line 17)
  /api/products [api] (line 15)
  /api/profile [api] (line 18)
  /api/users [api] (line 13)
  /api/users/${userId}/posts [api] (line 19)
  /dashboard (line 21)
  /login (line 21)
  /settings/billing (line 21)

BASE / ABSOLUTE URLS (2)
  https://api.acme-demo.example/graphql (line 7)
  https://api.acme-demo.example/v1 (line 11)

CONFIG KEYS (7)
  apiBase = https://api.acme-demo.example/v1 (line 7)
  apiKey [sensitive — see potential secrets] (line 7)
  apiVersion = 2026-01-15 (line 7)
  baseURL = https://api.acme-demo.example/v1 (line 11)
  clientId = acme-web-client (line 7)
  graphqlUrl = https://api.acme-demo.example/graphql (line 7)
  token [sensitive, non-literal value] (line 22)

POTENTIAL SECRETS — REVIEW (5)
  Flagged for the owner to review. Nothing was transmitted.
  ⚠ Sensitive config key with literal value: apiK…_use (34 chars) (line 7)
  ⚠ JSON Web Token (JWT): eyJh…sw5c (156 chars) (line 8)
  ⚠ Google API key: AIza…ABCD (39 chars) (line 9)
  ⚠ Stripe secret key: sk_t…7890 (40 chars) (line 10)
  ⚠ Bearer token literal: Bear…_use (34 chars) (line 11)

SUMMARY: 7 endpoints · 10 routes · 2 base URLs · 7 config keys · 5 potential secrets
Reminder: run only on applications you own or are explicitly authorized to test.

The same run as JSON (--json, excerpt):

{
  "tool": "web-surface-mapper",
  "source": "sample/app.bundle.js",
  "parser": "acorn-ast",
  "summary": { "endpoints": 7, "routes": 10, "baseUrls": 2, "configKeys": 7, "potentialSecrets": 5 },
  "endpoints": [
    { "kind": "http-client", "method": "POST", "url": "/api/orders", "dynamic": false, "line": 16 },
    { "kind": "axios", "method": "DELETE", "url": "/api/orders/42", "dynamic": false, "line": 17 }
  ],
  "baseUrls": [
    { "url": "https://api.acme-demo.example/graphql", "line": 7 }
  ],
  "potentialSecrets": [
    { "type": "Sensitive config key with literal value", "preview": "apiK…_use (34 chars)", "line": 7 },
    { "type": "JSON Web Token (JWT)", "preview": "eyJh…sw5c (156 chars)", "line": 8 }
  ]
}

Where it fits in a security-review workflow

  • Pre-ship self-audit. Run it against your production bundle in CI or before a release to catch a secret that leaked into the client, or an internal /admin/* route that shouldn't be referenced from the public app.
  • Recon on an authorized engagement. Quickly enumerate the server-side surface a single-page app talks to — endpoints, methods, and hidden routes — to seed deeper, properly authorized testing.
  • Triage a .js artifact. Point it at a saved bundle to get a fast map of what it calls and what it carries, without executing untrusted code.

Findings are a starting map, not a verdict: a flagged "secret" may be a public key or a false positive, and a missing endpoint may be built dynamically. Confirm anything important against the source.

Limitations (honest framing)

  • Static analysis only: URLs assembled entirely at runtime from many variables show up as [dynamic] or not at all.
  • Secret detection matches shapes of known credential formats; always verify before treating a match as a live, sensitive secret.
  • The regex fallback (no acorn) can't read a fetch options object, so some methods default to GET — install acorn for accurate methods.

Project layout

web-surface-mapper/
├── bin/cli.js          # CLI: args, input loading, output
├── src/analyzer.js     # static analysis (AST + regex passes)
├── src/report.js       # human-readable console report
├── sample/app.bundle.js# synthetic demo bundle (fake data only)
├── package.json
├── LICENSE
└── README.md

License

MIT © 2026 Tyler Milam (Golden Rock)

About

Ethical static analyzer that maps a web app's own JS bundle - endpoints, routes, leaked secrets - for authorized self-audit (Node CLI).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages