LinkFinder: extracting endpoints from JavaScript bundles

LinkFinder · MIT

LinkFinder parses JavaScript files and pulls out anything that looks like an endpoint. Modern front ends ship their entire routing table to the browser, which means the bundle is a fairly complete description of the API — including routes the UI never calls.

Install

git clone https://github.com/GerbenJavado/LinkFinder.git
cd LinkFinder && pip install -r requirements.txt
python linkfinder.py -h

Core commands

# one JS file, plain output
python linkfinder.py -i https://example.com/static/app.js -o cli

# every script on a page
python linkfinder.py -i https://example.com -d -o cli

# a whole domain from the Wayback corpus
python linkfinder.py -i "https://example.com/*" -o results.html

# a local bundle
python linkfinder.py -i ./app.bundle.js -o cli

-o cli prints to stdout, which is what you want in a pipeline; the default writes an HTML report.

Output

One candidate endpoint per line:

/api/v2/users
/api/v2/admin/impersonate
/internal/healthz

Where it sits in Tandera

LinkFinder runs in the analyze phase of recon_web_lite and recon_web_full, against the JavaScript that katana retrieved during crawling. It sits alongside jxscout and retirejs, which read the same bundles for different things — secrets and vulnerable dependencies respectively.

The endpoints it recovers rejoin the URL corpus and become probe targets.

Using it in a pentest

Admin routes are shipped to every user. A front end that hides an admin panel by not rendering the button still contains the route. /api/v2/admin/impersonate in a bundle served to anonymous users is worth testing immediately — if it is not authorised server-side, that is your critical.

Expect noise. The regex matches path-like strings, so you will get CSS fragments, MIME types and version numbers. Filter, then probe:

python linkfinder.py -i https://example.com -d -o cli 
  | grep -E '^/' | sort -u 
  | sed 's|^|https://example.com|' | httpx -silent -status-code

Source maps are better when they exist. If app.js.map is served, you get original sources rather than minified output. Always check.

early access

Get Tandera before your next engagement.

Join the waitlist for early access. We are onboarding pentest teams in waves.

Priority onboarding for pentest teams.
A direct line to the people building it.
Early-access pricing, locked in.

No spam, no card. Unsubscribe anytime.

enespt-br