Your tech stack is public. Does that matter?
Attackers don't guess your framework. Your headers announce it.
You can tell what a site runs without asking the owner anything. The site tells you itself, every single response, in plain text. That's fingerprinting, and it's the quietest part of reconnaissance because it costs the observer nothing and triggers nothing on your end.
So the real question isn't whether your stack is detectable. It is. The question is whether the specific things it's leaking actually narrow an attacker's job, and for most sites the answer is yes.
How a stranger reads your stack
Open your terminal and run curl -I https://yoursite.com. You'll get the response headers, and they're more talkative than you'd like.
A Server: Apache/2.4.41 (Ubuntu) header names your web server, its version, and your OS family. An X-Powered-By: PHP/7.4.3 header names your language and its exact patch level. Frameworks leave their own marks: a X-Powered-By: Next.js header, a Set-Cookie: laravel_session= cookie, a __cfduid or specific cookie name that only one framework sets. WordPress announces itself with a <meta name="generator" content="WordPress 5.8"> tag in the HTML and a wp-content/ path in every asset URL. None of this is hidden. It's how the software ships by default.
There are tools that do nothing but this at scale, fingerprinting millions of sites and indexing them by technology and version. Someone hunting for vulnerable installs doesn't browse the web looking for victims. They query an index: show me every site running this CMS at this version, then go down the list.
Why a version number is a shopping list
A framework name is mildly useful to an attacker. A framework name with an exact version is a plan.
Public vulnerability databases are organized by software and version. When a CVE drops for PHP 7.4.3 or Apache 2.4.41 or a given CMS release, the matching exploit often follows within days, and it's published openly. So when your X-Powered-By header pins you to a version with a known, exploitable bug, you've done the targeting for them. They don't probe to discover whether you're vulnerable. They read your header, match it against the list, and arrive already knowing.
With a version, an attacker moves from "this site might be exploitable" to "this site is exploitable, here's the exploit." That gap is the whole value of fingerprinting, and it's why broadcasting versions you don't need to broadcast is a free gift you keep giving.
Old client-side libraries play the same game in reverse. An outdated jQuery 1.12 or a Lodash version with a known prototype-pollution CVE sits right there in your loaded scripts, version string and all. Anyone can read it, and the matching advisory is a search away.
Quieting the broadcast
Removing version headers is not a fix for being out of date, and you shouldn't pretend it is. If you're running a vulnerable version, hiding the number buys you very little against a determined attacker who'll just probe behaviorally. Patch first. Always patch first.
That said, you also shouldn't volunteer the version to every passing crawler and automated scanner, because most attacks are opportunistic and automated, and they key off exactly these strings. Suppressing them drops you out of the easy index. It's cheap and worth doing.
# nginx, leaking by default # Server: nginx/1.18.0 # X-Powered-By: Express # response headers as shipped: Server: nginx/1.18.0 X-Powered-By: Express
Set server_tokens off in nginx. Call app.disable("x-powered-by") in Express. Strip the X-Generator tag your CMS adds. Update or remove the stale frontend libraries that carry their own version strings. Each one closes a line in your profile.
Fingerprinting is one slice of the larger picture an outsider builds during passive reconnaissance of your whole site, and it's one of the easiest to see for yourself. SurfaceCheckr reads your site the way that index does, from the outside, no access to your servers, and reports back exactly which technologies and versions you're broadcasting and which of them match a known issue. It won't patch your server, and it won't test what's behind your login. It tells you what you're announcing, which is the part you can't see from where you sit.
Find it before someone else does.
Paste your domain. The grade and issue count are free, and you'll see in a couple of minutes exactly what's reachable from outside.