
JShunter is a Go CLI that parses JavaScript structurally to extract endpoints, chunk manifests, and genuinely leaked credentials for authorized penetration testers and bug bounty hunters.
| Tool | cc1a2b/JShunter — command-line JavaScript security analyzer with structural secrets detection and chunk-graph endpoint discovery |
| Category | web reconnaissance and static JavaScript analysis |
| Primary Use | extracting endpoints, routes, and hardcoded credentials from client-side JavaScript during authorized assessments and bug bounty engagements |
| Safe Use | Use only against applications you own or have written authorization to test, such as sanctioned penetration tests, bug bounty programs in scope, and internal code audits. |
| Telemetry Note | Every scan generates HTTP requests against the target that are visible in server and WAF logs; the tool's own mitigations (rate limiting -R, proxy -p, UA rotation -U) shape but do not eliminate that footprint. |
JShunter is a single-binary Go tool, MIT-licensed and sitting at 537 stars, that turns the client-side JavaScript of a web application into a structured map of its attack surface. Where most tools in this niche run regex patterns over raw bytes, JShunter ships what its README calls a structural detection engine: a single-pass ECMAScript scanner that classifies every byte of a response as string literal, template literal, comment, regex literal, or code before any detection rule is evaluated. That architectural choice is the most interesting thing about the project, and it has consequences for accuracy that practitioners will immediately recognize. The repo targets Go 1.25+ and runs on Linux, macOS, and Windows, which makes it easy to drop into most assessment toolchains.
The core problem the structural engine solves is the false-positive plague in secrets detection. The README is refreshingly explicit about it: a regex has no idea what it matched, so the same forty base64 characters mean "credential" inside a string literal, "chunk hash" inside a minified identifier, and nothing at all when they straddle two adjacent tokens. JShunter answers this with region gating, rejecting matches inside regex literals as patterns rather than values, rejecting matches that cross token boundaries, and treating matches in code as identifier fragments. This is the kind of engineering that separates tools that produce triage-able output from tools that produce noise an analyst abandons after the first hundred alerts.
Beyond region gating, the engine recovers binding context. Instead of scanning a fixed window for the word key, it extracts the identifier or property a candidate value is actually bound to, so const stripeSecret = "..." and {contentHash: "..." are read very differently even when the value shape is identical. Sibling key-sets extend this idea to whole objects: a Firebase web config, an Algolia search config, a Segment analytics config, and a Supabase browser client are recognized by the shape of the object their members sit in. Value-shape analysis then classifies digests, UUIDs, paths, placeholders, and base64 that decodes to a PNG, font, JSON document, or English sentence for what they are rather than what they look like.
A particularly mature touch is exposure classification. Values the issuer publishes on purpose — Stripe publishable keys, Mapbox public tokens, Supabase anon JWTs read from their own role claim, Twilio SIDs — are classified as intentionally public rather than reported as leaks, with --include-public available to surface them anyway. This matters operationally because a huge fraction of "secrets" found in frontend bundles are publishable keys by design, and drowning a report in them erodes trust in the real findings. The engine is also defensively conservative: rejection rules only apply when the input is confidently JavaScript or JSON, so a misclassified input like a .env file or raw HTML can never have a secret suppressed by the structural layer. --no-structural reverts to v0.7 behavior if you want to compare.
Findings carry their reasoning with them. In --json, --ndjson, and SARIF output, each result embeds an evidence object containing the region (string-literal), the role (assignment), the binding (awsAccessKeyId), the shape (opaque-token), and a signal list with per-signal deltas. For anyone who has had to defend a finding to a development team, this audit trail is a genuine differentiator — you can show why something is a credential rather than asserting it. --stats completes the picture by reporting what each pipeline stage dropped, keeping the whole detection process accountable rather than opaque.
The second headline feature is the chunk graph, exposed via -G. Modern bundlers ship one entry bundle plus hundreds of lazily loaded chunks whose URLs are assembled at runtime from an inlined manifest, which means crawlers never see them and nothing links to them. -G recovers that manifest and prints the full asset list plus a client route table. The README demonstrates this on a Next.js chunk URL, reporting 214 chunks and 37 routes including things like /admin/users/:id — the kind of route that defines where an authorized tester should look next. Supported runtimes include webpack 4 and 5 (__webpack_require__.u, miniCssF, jsonpScriptSrc), Next.js build manifests, Vite and Rollup (__vite__mapDeps, __vitePreload), plain dynamic import(), and route tables from React Router, Vue Router, and Angular.
The output is tab-separated and deduplicated specifically so it pipes back into itself, and the README shows the intended two-stage workflow: run -G -q on the entry bundle, extract the chunk URLs with awk, then feed the resulting list back through -l with -s for secrets scanning across the full chunk fleet. This composability is good Unix hygiene and reflects how operators actually work during a scoped assessment — discovery and exploitation of findings are deliberately separate phases. In an authorized engagement, this is how you enumerate everything the application ships to browsers before deciding what deserves deeper manual review.
The security analysis suite beyond secrets is broad. -s covers API keys, tokens, and hardcoded credentials; -x handles JWT extraction, validation, and payload inspection; -F analyzes Firebase configuration and database URLs; -P and -PU discover hidden parameters and URL parameters with full context; and -g performs GraphQL schema detection and query extraction. There is also -B for WAF bypass pattern detection and -i for filtering internal endpoints, which is useful for prioritizing findings that reveal private infrastructure. None of this is exploitation tooling; it is enumeration and classification, which is exactly the right scope for a reconnaissance utility.
For deeper analysis of hostile or minified code, JShunter includes a deobfuscation engine (-d), a source map parser (-m) that can recover original source code when .map files are exposed, obfuscation classification (-z), and eval analysis (-e) covering eval(), Function(), and runtime code generation. The source map capability deserves a note from the defensive side as well: exposed .map files on production assets are a common misconfiguration that hands attackers the entire readable sourcebase, and scanning your own deployments for this is a cheap, high-value control check.
The networking layer covers the practical concerns of an authorized engagement: repeatable custom headers via -H, cookie management with -c, user-agent control or rotation with -U, configurable delays with -R, retries with exponential backoff via -y, timeouts with -T, thread control with -t, and full proxy support through -p for routing traffic through Burp Suite over HTTP, HTTPS, or SOCKS5. The README's own framing of these as rate limiting "to avoid detection" is worth reading critically — in practice, on an authorized test, -R exists to keep your scanner from hammering someone's production infrastructure, and -p exists so you can see and log everything you send. Use them that way.
Installation follows the standard Go path, and the README recommends go install -v github.com/cc1a2b/jshunter/cmd/jshunter@latest, with prebuilt release binaries also available from the repo's releases page for the three supported platforms. Verification is a simple jshunter --h after install. Output formats round out the reporting story: color-coded console output for interactive use, -j JSON for automation, -C CSV for management reporting, -n for direct Burp Suite export, and -q quiet mode for CI/CD integration. The README notes the demo video shows fake test secrets, which is a good sign of a project that takes responsible presentation seriously.
Where does JShunter fit? For authorized penetration testers and bug bounty researchers, it consolidates what usually takes three or four separate tools — endpoint extraction, secrets scanning, source map recovery, chunk discovery — into one structural analyzer with auditable evidence output. For defensive teams, it doubles as a hygiene checker: run it against your own production bundles before attackers do, and treat every finding with an exposure: secret evidence object as a rotation-and-investigate item. The structural engine's refusal to suppress findings on non-JavaScript inputs is a thoughtful safety property, and the --stats stage accounting makes the tool trustworthy in a way most pattern-matching scanners never achieve. This is a well-engineered addition to the client-side recon toolkit.
cc1a2b/JShunter.Educational analysis for authorized security professionals. Use only in controlled, authorized environments.
0 comentários:
Post a Comment
Note: Only a member of this blog may post a comment.