Tech-stack fingerprinting
When it applies
The start of any web/API engagement, before you pick techniques. Knowing the stack turns a generic
"test everything" into a targeted plan: a Rails app routes to mass-assignment and deserialization,
a GraphQL backend to api-graphql, a WAF in front changes your payloads-waf-bypass approach, and
a pinned version turns into a CVE shortlist. It is passive OSINT — public signals only, no exploit.
Why it works
Applications advertise themselves constantly: response headers, cookie names, HTML generator tags,
JS bundle names, error pages, TLS certs, DNS/CDN records, public repos, and job postings all leak
the stack. Cross-correlating several weak signals gives a high-confidence picture no single tool
produces — and confidence is what keeps you from scoring a CVE against a wrong guess.
Method
Work outside-in, then correlate. Keep every claim tagged with the signal that supports it and a
confidence level.
- Infrastructure first (asset inventory). CDN/WAF, DNS, TLS/CT logs, cloud provider, and the
domain/subdomain/IP footprint (
recon-subdomain-enum, recon-dns-analysis). This scopes everything
else and often reveals origin IPs behind a CDN.
- Frontend. JS frameworks and meta-frameworks (Next/Nuxt/Angular), CSS libs, build tooling,
and CMS from the DOM,
<meta name="generator">, bundle filenames, and source maps.
whatweb <url>, Wappalyzer, and reading the loaded JS.
- Backend. Web server, runtime/language, framework, and CMS from
Server/X-Powered-By
headers, cookie names (PHPSESSID, JSESSIONID, _rails_session, csrftoken), default error
pages, and path conventions (/wp-json, /api/v1, .aspx).
- Security surface. Security headers, CSP (which reveals third-party hosts/SaaS),
security.txt, email auth (SPF/DMARC), and the WAF vendor.
- OSINT. Public GitHub/GitLab repos, job postings/ATS (they name the exact stack), and the
Wayback Machine for historical/leaked endpoints and migrated tech.
- Correlate. Cross-validate signals, resolve conflicts (a backported
Server banner vs. a
framework's real version), score confidence, and produce the routing decision.
Routing (what the result feeds)
- CMS/framework identified → the matching
web-* classes (e.g. WordPress → plugin CVEs, upload;
Rails/Spring → deserialization, mass assignment).
- API style →
api-graphql, api-grpc, api-bola.
- WAF present →
payloads-waf-bypass.
- Pinned versions → CVE shortlist (enrich against the NVD), gated by real applicability, not the banner.
- Cloud/CDN →
cloud-* and origin-IP discovery.
Gotchas
- One signal is a guess; correlation is a finding. A
Server: header alone is spoofable and
backported — don't route a version-specific CVE off it. Require a second corroborating signal.
- CDN/WAF masks the origin — the stack you fingerprint at the edge may not be the origin's;
hunt the origin IP before concluding.
- Passive means passive — no auth, no active exploitation here; that's for the domain skills
this one routes to. Stay within
tradecraft-scope-roe.
- Wildcard/parked hosts and shared infra can attribute the wrong stack to a domain — confirm
the host actually serves the app.
Verify success
A stack profile where each component names the signal and confidence behind it, and a concrete
"test these next" list of skills + a CVE shortlist — not a raw dump of tool output.
References
Wappalyzer/WhatWeb signatures; MITRE ATT&CK T1592/T1595 (reconnaissance); NIST NVD for version→CVE.
1---2name: recon-techstack-fingerprinting3description: Passively identify a target's full technology stack — frontend framework, backend runtime, server, CMS, CDN/WAF, cloud, and versions — from public signals, then route to the right attack skills and CVEs. Load at the start of a web/API assessment, when choosing which techniques apply, or when "what is this built with / what CVEs match". Signals: a new domain in scope, unknown stack, "fingerprint", "what framework", version-to-CVE matching.4---56# Tech-stack fingerprinting78## When it applies9The start of any web/API engagement, before you pick techniques. Knowing the stack turns a generic10"test everything" into a targeted plan: a Rails app routes to mass-assignment and deserialization,11a GraphQL backend to `api-graphql`, a WAF in front changes your `payloads-waf-bypass` approach, and12a pinned version turns into a CVE shortlist. It is passive OSINT — public signals only, no exploit.1314## Why it works15Applications advertise themselves constantly: response headers, cookie names, HTML generator tags,16JS bundle names, error pages, TLS certs, DNS/CDN records, public repos, and job postings all leak17the stack. Cross-correlating several weak signals gives a high-confidence picture no single tool18produces — and confidence is what keeps you from scoring a CVE against a wrong guess.1920## Method21Work outside-in, then correlate. Keep every claim tagged with the signal that supports it and a22confidence level.23241. **Infrastructure first (asset inventory).** CDN/WAF, DNS, TLS/CT logs, cloud provider, and the25 domain/subdomain/IP footprint (`recon-subdomain-enum`, `recon-dns-analysis`). This scopes everything26 else and often reveals origin IPs behind a CDN.272. **Frontend.** JS frameworks and meta-frameworks (Next/Nuxt/Angular), CSS libs, build tooling,28 and CMS from the DOM, `<meta name="generator">`, bundle filenames, and source maps.29 `whatweb <url>`, Wappalyzer, and reading the loaded JS.303. **Backend.** Web server, runtime/language, framework, and CMS from `Server`/`X-Powered-By`31 headers, cookie names (`PHPSESSID`, `JSESSIONID`, `_rails_session`, `csrftoken`), default error32 pages, and path conventions (`/wp-json`, `/api/v1`, `.aspx`).334. **Security surface.** Security headers, CSP (which reveals third-party hosts/SaaS),34 `security.txt`, email auth (SPF/DMARC), and the WAF vendor.355. **OSINT.** Public GitHub/GitLab repos, job postings/ATS (they name the exact stack), and the36 Wayback Machine for historical/leaked endpoints and migrated tech.376. **Correlate.** Cross-validate signals, resolve conflicts (a backported `Server` banner vs. a38 framework's real version), score confidence, and produce the routing decision.3940## Routing (what the result feeds)41- CMS/framework identified → the matching `web-*` classes (e.g. WordPress → plugin CVEs, upload;42 Rails/Spring → deserialization, mass assignment).43- API style → `api-graphql`, `api-grpc`, `api-bola`.44- WAF present → `payloads-waf-bypass`.45- Pinned versions → CVE shortlist (enrich against the NVD), gated by real applicability, not the banner.46- Cloud/CDN → `cloud-*` and origin-IP discovery.4748## Gotchas49- **One signal is a guess; correlation is a finding.** A `Server:` header alone is spoofable and50 backported — don't route a version-specific CVE off it. Require a second corroborating signal.51- **CDN/WAF masks the origin** — the stack you fingerprint at the edge may not be the origin's;52 hunt the origin IP before concluding.53- **Passive means passive** — no auth, no active exploitation here; that's for the domain skills54 this one routes to. Stay within `tradecraft-scope-roe`.55- **Wildcard/parked hosts** and shared infra can attribute the wrong stack to a domain — confirm56 the host actually serves the app.5758## Verify success59A stack profile where each component names the signal and confidence behind it, and a concrete60"test these next" list of skills + a CVE shortlist — not a raw dump of tool output.6162## References63Wappalyzer/WhatWeb signatures; MITRE ATT&CK T1592/T1595 (reconnaissance); NIST NVD for version→CVE.