Recon
Systematically discover alternative endpoints, bypasses, and undocumented access paths. Use this after you have a working flow (via browser-navigate + network-debug) and want to find simpler or more efficient approaches.
1. Map the Attack Surface
Subdomain enumeration
- Certificate Transparency —
https://crt.sh/?q=%25.example.com&output=json lists all issued certificates
- Reverse DNS —
dig -x <IP> to find co-hosted domains on the same server
- DNS records —
dig example.com ANY for MX, TXT, CNAME revealing internal hosts
- Response headers —
X-Served-By, X-Backend-Server, Via in captured traffic
- JavaScript bundles — grep captured JS for hardcoded URLs and subdomains
- CORS headers —
Access-Control-Allow-Origin reveals sibling domains
Path enumeration
robots.txt — disallowed paths often point to interesting endpoints
sitemap.xml — URL structure and available pages
- OpenAPI/Swagger —
/swagger.json, /openapi.json, /api-docs, /v1/docs
- GraphQL —
/graphql, /graphiql. Run introspection query if found
- Health/status —
/health, /status, /version, /info
Tech stack identification
- Response headers —
X-Powered-By, Server, X-Cache
- Cookie names —
JSESSIONID (Java), PHPSESSID (PHP), connect.sid (Express)
- Error pages — trigger 404/500 to identify framework
- HTML source —
__NEXT_DATA__ (Next.js), __NUXT__ (Nuxt), generator meta tags
2. Alternative Access Surfaces
- Mobile APIs — proxy a phone, compare mobile vs desktop responses
- Mobile web —
m.example.com or responsive variants
- Export/bulk endpoints —
/export, /download, ?format=csv
- Print views —
/print, ?print=true
- RSS/Atom —
/feed, /rss, /atom.xml
- Developer/partner APIs —
developer.example.com, /developers
3. API Version and Format Exploration
- Version probing — try v1, v2, v3; check for version headers (
API-Version, Accept-Version)
- Format negotiation —
Accept: application/json on HTML pages, JSONP via ?callback=x
- GraphQL alongside REST — same data, different access control or rate limits
- Content-Type alternatives — form-encoded vs JSON POST bodies may have different validation
4. Embedded Data Extraction
Pages often embed all their data in HTML, avoiding the need for separate API calls.
In-browser extraction
// JSON data blocks
evaluate_script(function: "() => { return [...document.querySelectorAll('script[type=\"application/json\"]')].map(s => s.textContent.substring(0, 200)) }")
// Linked data
evaluate_script(function: "() => { return [...document.querySelectorAll('script[type=\"application/ld+json\"]')].map(s => JSON.parse(s.textContent)) }")
// Inline JSON assignments
evaluate_script(function: "() => { return [...document.querySelectorAll('script:not([src])')].map(s => s.textContent).filter(t => t.includes('window.__') || t.includes('initialState') || t.includes('pageData')).map(t => t.substring(0, 300)) }")
From captured traffic
- Script tags —
<script type="application/json"> and <script type="application/ld+json"> in HTML responses. Use powhttp_query_body with JQ expressions to extract.
- Inline assignments —
window.__DATA__ = {, "sectionPopupData":, var initialState = in script blocks
- Linked data URLs — scripts may reference internal API URLs not called during page load
Use powhttp_get_entry(body_mode: "full") on HTML page loads to inspect raw source.
5. JavaScript Source Analysis
- Bundle grep — search for
baseURL, apiUrl, fetch(", axios.create in JS files
- Source maps — append
.map to JS URLs to get original source
- Build-time env vars —
NEXT_PUBLIC_, REACT_APP_, VUE_APP_ prefixed variables
- Webpack chunks — named chunks correspond to features, revealing endpoint patterns
6. Platform-Specific Endpoints
- Next.js —
/_next/data/<buildId>/<path>.json returns page data as JSON
- Nuxt.js —
/_payload.json for page data
- Shopify —
/products.json, /collections.json, Storefront API
- WordPress —
/wp-json/wp/v2/ REST API
- Elasticsearch —
/_search, /_mapping if exposed
- Firebase —
<project>.firebaseio.com/.json if rules allow
7. Related Site Analysis
- Same parent company — shared backends, consistent endpoint patterns
- Same platform — one site's patterns apply to all sites on that platform
- Community resources — GitHub for unofficial SDKs:
site:github.com "example.com" api
- Wayback Machine — old JS bundles reveal historical endpoints that may still be active
- CORS headers —
Access-Control-Allow-Origin reveals sibling domains
8. Auth and Session Shortcuts
Session inspection
// Get all cookies
evaluate_script(function: "() => { return document.cookie }")
// Inspect localStorage keys
evaluate_script(function: "() => { return Object.keys(localStorage) }")
// Get specific localStorage value
evaluate_script(function: "() => { return localStorage.getItem('authToken') }")
// Decode a JWT from a cookie
evaluate_script(function: "() => { const token = document.cookie.split('; ').find(c => c.startsWith('jwt=')); if (!token) return null; const payload = token.split('.')[1]; return JSON.parse(atob(payload.split('=')[0].replace(/-/g, '+').replace(/_/g, '/'))) }")
Session lifecycle
- Minimal cookie set — test subsets to find minimum required cookies. Use
powhttp_get_entry(include_headers: true) to check which cookies the server actually reads.
- Token reuse — web auth tokens on mobile endpoints and vice versa
- JWT inspection — decode expiry (
exp field), understand refresh lifecycle
- Silent refresh — GET homepage may renew session without re-auth
- Cookie dependency mapping — which cookies the server reads vs ignores
- Unauthorized detection — some sites signal expiry by clearing cookies (
Set-Cookie with past expiration) rather than returning error status
Endpoint discovery from known patterns
- URL pattern inference — if
/listings/getListings exists, try /sales/getSales, /orders/getOrders
- Query parameter exploration — test
pageSize, limit, offset, sort, dateFrom, dateTo, status, filter
- Larger page sizes — default pagination is often conservative (20-50). Test
pageSize=500 or pageSize=1000.
Response schema analysis
- Abbreviated field names — minified APIs use short keys (
"i" for ID, "n" for name). Use powhttp_query_body to extract samples and infer meaning.
- Nullable fields — compare multiple responses with
powhttp_describe_endpoint to see field consistency
- Enum collection —
powhttp_query_body with deduplicate: true across a cluster to collect all status/type values
- Nested pagination — check top-level structure for wrapper objects (
{"items": [...], "total": 500, "page": 1})
Keys in source
apiKey, token, client_id in JS bundles or HTML
Geo/locale headers — X-Forwarded-For, Accept-Language effects on responses
1---2name: recon3description: Systematically discover alternative endpoints, bypasses, and undocumented access paths on a target platform. Use after the normal flow works to find simpler or more efficient approaches.4---56# Recon78Systematically discover alternative endpoints, bypasses, and undocumented access paths. Use this after you have a working flow (via browser-navigate + network-debug) and want to find simpler or more efficient approaches.910## 1. Map the Attack Surface1112### Subdomain enumeration1314- **Certificate Transparency** — `https://crt.sh/?q=%25.example.com&output=json` lists all issued certificates15- **Reverse DNS** — `dig -x <IP>` to find co-hosted domains on the same server16- **DNS records** — `dig example.com ANY` for MX, TXT, CNAME revealing internal hosts17- **Response headers** — `X-Served-By`, `X-Backend-Server`, `Via` in captured traffic18- **JavaScript bundles** — grep captured JS for hardcoded URLs and subdomains19- **CORS headers** — `Access-Control-Allow-Origin` reveals sibling domains2021### Path enumeration2223- `robots.txt` — disallowed paths often point to interesting endpoints24- `sitemap.xml` — URL structure and available pages25- **OpenAPI/Swagger** — `/swagger.json`, `/openapi.json`, `/api-docs`, `/v1/docs`26- **GraphQL** — `/graphql`, `/graphiql`. Run introspection query if found27- **Health/status** — `/health`, `/status`, `/version`, `/info`2829### Tech stack identification3031- **Response headers** — `X-Powered-By`, `Server`, `X-Cache`32- **Cookie names** — `JSESSIONID` (Java), `PHPSESSID` (PHP), `connect.sid` (Express)33- **Error pages** — trigger 404/500 to identify framework34- **HTML source** — `__NEXT_DATA__` (Next.js), `__NUXT__` (Nuxt), generator meta tags3536## 2. Alternative Access Surfaces3738- **Mobile APIs** — proxy a phone, compare mobile vs desktop responses39- **Mobile web** — `m.example.com` or responsive variants40- **Export/bulk endpoints** — `/export`, `/download`, `?format=csv`41- **Print views** — `/print`, `?print=true`42- **RSS/Atom** — `/feed`, `/rss`, `/atom.xml`43- **Developer/partner APIs** — `developer.example.com`, `/developers`4445## 3. API Version and Format Exploration4647- **Version probing** — try v1, v2, v3; check for version headers (`API-Version`, `Accept-Version`)48- **Format negotiation** — `Accept: application/json` on HTML pages, JSONP via `?callback=x`49- **GraphQL alongside REST** — same data, different access control or rate limits50- **Content-Type alternatives** — form-encoded vs JSON POST bodies may have different validation5152## 4. Embedded Data Extraction5354Pages often embed all their data in HTML, avoiding the need for separate API calls.5556### In-browser extraction5758```javascript59// JSON data blocks60evaluate_script(function: "() => { return [...document.querySelectorAll('script[type=\"application/json\"]')].map(s => s.textContent.substring(0, 200)) }")6162// Linked data63evaluate_script(function: "() => { return [...document.querySelectorAll('script[type=\"application/ld+json\"]')].map(s => JSON.parse(s.textContent)) }")6465// Inline JSON assignments66evaluate_script(function: "() => { return [...document.querySelectorAll('script:not([src])')].map(s => s.textContent).filter(t => t.includes('window.__') || t.includes('initialState') || t.includes('pageData')).map(t => t.substring(0, 300)) }")67```6869### From captured traffic7071- **Script tags** — `<script type="application/json">` and `<script type="application/ld+json">` in HTML responses. Use `powhttp_query_body` with JQ expressions to extract.72- **Inline assignments** — `window.__DATA__ = {`, `"sectionPopupData":`, `var initialState =` in script blocks73- **Linked data URLs** — scripts may reference internal API URLs not called during page load7475Use `powhttp_get_entry(body_mode: "full")` on HTML page loads to inspect raw source.7677## 5. JavaScript Source Analysis7879- **Bundle grep** — search for `baseURL`, `apiUrl`, `fetch("`, `axios.create` in JS files80- **Source maps** — append `.map` to JS URLs to get original source81- **Build-time env vars** — `NEXT_PUBLIC_`, `REACT_APP_`, `VUE_APP_` prefixed variables82- **Webpack chunks** — named chunks correspond to features, revealing endpoint patterns8384## 6. Platform-Specific Endpoints8586- **Next.js** — `/_next/data/<buildId>/<path>.json` returns page data as JSON87- **Nuxt.js** — `/_payload.json` for page data88- **Shopify** — `/products.json`, `/collections.json`, Storefront API89- **WordPress** — `/wp-json/wp/v2/` REST API90- **Elasticsearch** — `/_search`, `/_mapping` if exposed91- **Firebase** — `<project>.firebaseio.com/.json` if rules allow9293## 7. Related Site Analysis9495- **Same parent company** — shared backends, consistent endpoint patterns96- **Same platform** — one site's patterns apply to all sites on that platform97- **Community resources** — GitHub for unofficial SDKs: `site:github.com "example.com" api`98- **Wayback Machine** — old JS bundles reveal historical endpoints that may still be active99- **CORS headers** — `Access-Control-Allow-Origin` reveals sibling domains100101## 8. Auth and Session Shortcuts102103### Session inspection104105```javascript106// Get all cookies107evaluate_script(function: "() => { return document.cookie }")108109// Inspect localStorage keys110evaluate_script(function: "() => { return Object.keys(localStorage) }")111112// Get specific localStorage value113evaluate_script(function: "() => { return localStorage.getItem('authToken') }")114115// Decode a JWT from a cookie116evaluate_script(function: "() => { const token = document.cookie.split('; ').find(c => c.startsWith('jwt=')); if (!token) return null; const payload = token.split('.')[1]; return JSON.parse(atob(payload.split('=')[0].replace(/-/g, '+').replace(/_/g, '/'))) }")117```118119### Session lifecycle120121- **Minimal cookie set** — test subsets to find minimum required cookies. Use `powhttp_get_entry(include_headers: true)` to check which cookies the server actually reads.122- **Token reuse** — web auth tokens on mobile endpoints and vice versa123- **JWT inspection** — decode expiry (`exp` field), understand refresh lifecycle124- **Silent refresh** — GET homepage may renew session without re-auth125- **Cookie dependency mapping** — which cookies the server reads vs ignores126- **Unauthorized detection** — some sites signal expiry by clearing cookies (`Set-Cookie` with past expiration) rather than returning error status127128### Endpoint discovery from known patterns129130- **URL pattern inference** — if `/listings/getListings` exists, try `/sales/getSales`, `/orders/getOrders`131- **Query parameter exploration** — test `pageSize`, `limit`, `offset`, `sort`, `dateFrom`, `dateTo`, `status`, `filter`132- **Larger page sizes** — default pagination is often conservative (20-50). Test `pageSize=500` or `pageSize=1000`.133134### Response schema analysis135136- **Abbreviated field names** — minified APIs use short keys (`"i"` for ID, `"n"` for name). Use `powhttp_query_body` to extract samples and infer meaning.137- **Nullable fields** — compare multiple responses with `powhttp_describe_endpoint` to see field consistency138- **Enum collection** — `powhttp_query_body` with `deduplicate: true` across a cluster to collect all status/type values139- **Nested pagination** — check top-level structure for wrapper objects (`{"items": [...], "total": 500, "page": 1}`)140141### Keys in source142143- `apiKey`, `token`, `client_id` in JS bundles or HTML144- `Geo/locale headers` — `X-Forwarded-For`, `Accept-Language` effects on responses