How do I find out what a website is built with?
Identifying a site's stack from what it discloses — and understanding why disclosure is itself a finding.
Response headers, HTML fingerprints, asset paths and cookie names give most of it away. That is convenient for research and inconvenient for the site owner, because the same disclosure tells an attacker which known vulnerabilities to try first.
What sites disclose without meaning to
Response headers
curl -sI https://example.comServer:— the web server and frequently its exact version.X-Powered-By:— the runtime, commonly with a precise version number.X-Generator:— the CMS.X-Drupal-Cache,X-Shopify-Stage,X-Vercel-Idand similar — vendor-specific headers that identify the platform outright.Set-Cookie:names —PHPSESSID,JSESSIONID,laravel_session,_shopify_y. Each is a reliable fingerprint.
HTML and asset paths
<meta name="generator">— often the CMS and its version, stated outright.- Directory conventions:
/wp-content/,/sites/default/files/,/_next/static/,/_nuxt/. Each maps to one platform. - Build artefact naming — hashed bundle filenames differ recognisably between bundlers.
- Framework attributes left in the markup, such as
data-reactrootor Angular'sng-prefixes.
Third-party requests
What a page loads is as identifying as what it says. Analytics, tag managers, chat widgets, payment SDKs, font providers and consent tools each announce themselves by domain.
Why this matters for your own site
Fingerprinting is not merely a curiosity. Version disclosure meaningfully assists an attacker.
- A version number turns "probe everything" into "look up the known issues for this exact release and try those first".
- It makes automated mass exploitation cheap — scanning for one header and firing a matching payload requires no skill.
- It reveals your upgrade cadence. A version eighteen months old signals that patching is not routine.
Reducing your own disclosure
| Server | Change |
|---|---|
| nginx | server_tokens off; |
| Apache | ServerTokens Prod and ServerSignature Off |
| PHP | expose_php = Off in php.ini |
| Express | app.disable('x-powered-by') |
| Any | Remove the generator meta tag from your templates |
Cookie names and asset paths are much harder to disguise and generally not worth the effort — the platform will be identifiable regardless. Version numbers are the part that carries real risk and the part that is easy to remove.
Inference has limits, and should say so
Stack detection is fundamentally heuristic. A header can be spoofed, a CDN can add or strip headers in transit, and a static export leaves few traces of what generated it. Any honest report labels these findings as inferred rather than measured, because a confident claim about someone's infrastructure based on a cookie name deserves the qualification.
What our audit reports about this
Every item below is measured directly, not inferred. Run it against your own site and the result names the exact rule or header responsible.
- Every disclosing response header, with the value, including
Server,X-Powered-Byand platform-specific headers. - CMS, framework and server identification from headers, markup and asset paths — labelled as inferred rather than measured.
- A complete inventory of third-party origins the page loads, which is both a fingerprint and a privacy finding.
- Whether a version number specifically is disclosed, which is the part of fingerprinting that carries real risk.
For agents and scripts, the same measurement is at
/api/v1/tech?url=yoursite.com —
see the API documentation.
Related questions
Is hiding my stack worth doing?
Hiding version numbers, yes — it is a few lines of configuration and removes a free advantage. Hiding the platform entirely is largely futile and not worth engineering effort, since asset paths and cookie names give it away regardless.
Does removing headers break anything?
No. Server, X-Powered-By and generator tags are informational; nothing depends on them. Removing them is one of the few changes with a real benefit and no functional cost.
Can I trust detection results?
Treat them as strong hints rather than facts. Headers can be spoofed and CDNs rewrite them in transit, which is exactly why these findings are labelled inferred rather than measured.
Why does a CDN change what I see?
Edge servers commonly add their own headers, strip origin ones, and serve cached responses. What you observe is what the edge sends — which is the truth for visitors, even when it differs from your origin configuration.
Read next
What third parties does my website load?
Finding every external origin your pages pull in, and why the list is almost always longer than you think.
ReadWhat does my Server header reveal about me?
What version disclosure gives an attacker, why it is worth removing, and why removing it is not by itself a security measure.
ReadWhat are security headers and which do I need?
Six headers, what each actually prevents, and a configuration you can paste and adjust.
ReadWhat is a CDN and how do I tell if I am behind one?
How to detect a CDN from response headers, and why it changes what an audit of your site is actually measuring.
Read