Back to Articles

LinkFinder: Mining Hidden API Endpoints from JavaScript Files

[ View on GitHub ]

LinkFinder: Mining Hidden API Endpoints from JavaScript Files

Hook

Modern web applications leak their API surface through JavaScript bundles—LinkFinder turns minified code into a roadmap of every endpoint developers thought they’d hidden.

Context

Web application security testing has a discovery problem. Traditional crawlers follow links and form actions, but single-page applications and modern JavaScript frameworks route everything client-side. The real API structure lives in JavaScript files—often minified, sometimes obfuscated, always overlooked. Developers bundle route definitions, API calls, and endpoint strings directly into client code, creating an information disclosure vulnerability that’s simultaneously obvious and invisible. Before tools like LinkFinder, penetration testers manually searched through beautified JavaScript files with Ctrl+F, hoping to spot patterns like ‘/api/’ or ‘.json’. This worked for small applications but became untenable as JavaScript bundles grew to megabytes. Bug bounty hunters needed a way to systematically extract every possible endpoint from JavaScript files without spending hours reading code. LinkFinder addresses this need by automating the tedious reconnaissance phase and surfacing attack vectors that manual analysis would miss. By treating JavaScript as a data source rather than executable code, it reframes endpoint discovery as a parsing problem rather than a reverse engineering challenge.

Technical Insight

URL/File/Folder/Burp/Domain

Raw JavaScript

HTML Report

Text

Normalized JS

Extracted Endpoints

RegexEngine

Full URLs with Protocol

Absolute Paths /api/*

Relative Paths with /

Simple Relative Paths

Input Sources

Content Fetcher

jsbeautifier

Output Formatter

HTML Report

CLI Text Output

System architecture — auto-generated

LinkFinder’s architecture is deceptively simple but strategically designed. The core workflow runs JavaScript through jsbeautifier, then applies a composite regular expression to find URL patterns. This two-stage approach solves a critical problem: minified JavaScript compresses everything into unreadable single lines, making regex matching nearly impossible. Beautification normalizes the code structure, breaking statements across lines and adding whitespace that creates predictable patterns for regex engines.

The regex strategy uses four distinct patterns targeting different URL conventions developers use inconsistently. The first pattern catches full URLs with protocol and domain (https://api.example.com/users), which developers hardcode during debugging or when calling external services. The second matches absolute paths starting with a slash (/api/v1/profile) and dotted relative paths (../../config.json), common in structured applications with defined routing hierarchies. The third captures relative paths containing at least one slash (auth/login.php), while the fourth finds simple relative references without slashes (endpoint.json). This tiered approach compensates for the lack of semantic understanding—by casting a wide net across different syntactic patterns, LinkFinder catches endpoints regardless of how developers constructed them.

The input flexibility demonstrates thoughtful design for real-world workflows. Rather than forcing a single input method, LinkFinder accepts URLs, local files, entire folders with wildcards, or Burp Suite exports. The Burp integration is particularly clever for penetration testers already using intercepting proxies. You browse the application normally, Burp captures all JavaScript files, then you export with ‘Save selected items’ and feed the result directly to LinkFinder:

python linkfinder.py -i burp_js_files.txt -b -o findings.html

This bridges the gap between dynamic traffic analysis and static code analysis without context switching. The domain mode (-d flag) takes this further by crawling an entire domain, discovering JavaScript files automatically, and analyzing them in batch. For large applications, you can filter results with custom regex patterns. If you’re testing an API-heavy application, extract only API endpoints:

python linkfinder.py -i 'js_files/*.js' -r '^/api/' -o api_endpoints.html

The output format choice reveals performance considerations. HTML output provides human-readable results with syntax highlighting and organization, but requires running jsbeautifier on every file. The CLI output mode (-o cli) skips beautification entirely, printing raw matches to stdout. The README notes this makes it ‘very fast’—the beautification step appears to be the bottleneck. For automated pipelines where you’re piping results to other tools, CLI mode sacrifices readability for speed:

python linkfinder.py -i https://example.com/app.js -o cli | grep -E '/admin/'

The Chrome extension variant extends this concept to browser-based analysis, letting security researchers analyze JavaScript in real-time without leaving DevTools. This demonstrates the tool’s architectural flexibility—the core regex logic is modular enough to embed in different contexts.

Docker support standardizes the environment and eliminates dependency issues. The volume mount pattern ensures output persists after container termination:

docker run --rm -v $(pwd):/linkfinder/output linkfinder \
  -i http://example.com/bundle.js \
  -o /linkfinder/output/results.html

The required output path (/linkfinder/output) prevents the common mistake of writing results inside the container where they’d be lost.

Gotcha

LinkFinder’s regex-based approach guarantees false positives. String literals that look like URLs but aren’t actually endpoints will appear in results—variable names like ‘path/to/file’, comment examples, or string manipulation artifacts. The tool has no semantic understanding of JavaScript execution flow, so it can’t distinguish between a URL constant used for API calls versus a documentation string. You’ll need manual filtering to separate signal from noise, especially in large applications with extensive inline documentation.

Modern JavaScript tooling creates additional blind spots. Webpack, Rollup, and other bundlers often split code across chunks with dynamic imports and hashed filenames. LinkFinder won’t follow these relationships or reconstruct the module graph—it treats each file independently. If you’re testing an application built with modern frameworks using heavy code splitting, you might miss endpoints that are constructed dynamically or loaded conditionally.

The regular expressions themselves represent frozen assumptions about how developers write URLs. Heavily obfuscated code using string concatenation, template literals with complex expressions, or character encoding will evade detection. An endpoint constructed as '/api/' + 'users/' + id might not match if the concatenation happens across multiple lines or uses non-obvious patterns. LinkFinder finds the low-hanging fruit efficiently but won’t replace deeper static analysis for sophisticated applications actively trying to hide their structure.

Verdict

Use LinkFinder if you’re conducting security assessments on web applications and need to quickly enumerate potential attack surfaces hidden in JavaScript files. It excels at the reconnaissance phase of penetration testing and bug bounty hunting, particularly when paired with Burp Suite in your existing workflow. The tool shines on applications with large JavaScript bundles where manual analysis would take hours, and the HTML output format makes it easy to share findings with team members. Skip it if you need high-precision results with zero false positives for automated security pipelines—the regex approach trades accuracy for speed and coverage. Also skip it if you’re analyzing heavily obfuscated code or modern applications where Abstract Syntax Tree parsing would provide better results. LinkFinder works best as one component in a layered reconnaissance toolkit, handling breadth while you reserve deeper analysis tools for interesting findings.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/gerbenjavado-linkfinder.svg)](https://starlog.is/api/badge-click/developer-tools/gerbenjavado-linkfinder)