Website problems
Server and software version disclosure
Version disclosure is a site announcing which software it runs and which version, through response headers such as `Server` and `X-Powered-By`, through a `<meta name="generator">` tag, or through version strings appended to asset URLs. It is not a vulnerability: knowing the version does not create a weakness. What it does is remove a step — an automated scanner can match the version against a list of known issues instead of probing to find out.
Where the version appears
The `Server` response header, which many servers populate with a product name and version by default.
`X-Powered-By`, added by application runtimes and frameworks, frequently with a precise version.
A `<meta name="generator">` tag, which content management systems add to every page.
Version strings in asset URLs: `style.css?ver=6.4.2` is a version number in every page's HTML, and it survives the removal of every header.
Framework-specific headers, and error pages that render a stack trace or a default branded page naming the software.
Default files that ship with a product — a readme, a licence, an installer — which are reachable at a predictable path and state the version in their content.
What it actually costs
Obscurity is not a control, and nobody should treat removal as protection. A vulnerable version is vulnerable whether or not it announces itself.
What removal does is raise the cost of untargeted, automated attacks. Mass scanning works by matching a version against a list; a server that does not answer that question is skipped in favour of one that does.
It also removes a signal about patching discipline. A publicly stated version several releases behind tells an observer something about how the site is maintained.
And it matters more in aggregate than individually: one header is a hint, while a header plus a generator tag plus versioned assets plus a default error page is a complete inventory.
The honest framing is that this is a low-value, low-cost hardening step, worth doing because it is cheap rather than because it is important.
How to check it yourself
`curl -I https://example.com` prints the response headers. Read `Server`, `X-Powered-By`, and anything framework-specific.
In the HTML, look for `<meta name="generator">` and for version query strings on stylesheet and script URLs.
Request a path that does not exist and read the error page. Default error pages are frequently more talkative than successful responses.
Check the API and asset hosts separately. Headers are set per listener, and the main site is usually the one that was hardened.
Check the conventional default files for whatever software you run, which state the version regardless of any header.
How to remove it
Set `Server` to a constant, or unset it, at whichever layer terminates the connection. A CDN in front of the origin can usually override it in one setting.
Disable `X-Powered-By` in the application runtime. It is a single configuration flag in most frameworks.
Remove the generator meta tag, which is usually a one-line change or a setting.
Replace version query strings with a content hash. That keeps cache-busting working, which is what the version string was for, and stops the version being published.
Serve custom error pages so the defaults are never rendered.
Block the default documentation files at the web-server level rather than deleting them, so a product update does not restore them.
What matters more than removing it
Patching. A current version that announces itself is in a far better position than an old version that does not.
Knowing what you run. A version inventory that you maintain is the thing that makes patching possible, and it is the same information you are hiding from everyone else.
Automated dependency updates, so the gap between a release and its deployment is short by default rather than by effort.
So the order is: patch, then automate the patching, then remove the disclosure. Doing the third without the first two is the security equivalent of tidying.
How VeriFixScan detects it
`security.server_disclosure` reads the response headers of the crawled pages and reports the ones naming software and versions, with the header and its value.
`technology.versions` and `technology.inventory` report what the site appears to run and which versions are observable, which is the same information organised for the maintenance question rather than the hardening one.
`exposure.internal.paths` covers the adjacent disclosure of server paths in public assets.
The checks read what the server volunteers. They do not fingerprint by probing behaviour and do not test whether any version is exploitable.
Frequently asked questions
- Is version disclosure a vulnerability?
- No. It is an information disclosure that lowers the cost of targeting a site. A vulnerable version is equally vulnerable whether or not it announces itself.
- Should I remove the Server header entirely?
- Setting it to a constant or removing it are both fine. Some intermediaries expect the header to exist, so a fixed value is the safer of the two.
- What about version strings in asset URLs?
- Replace them with a content hash. That preserves cache-busting, which is why the version was there, and stops publishing the version on every page.
Sources
Related
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website