What 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.
A version number turns a broad probe into a targeted one. Server: nginx tells someone very little; Server: nginx/1.18.0 tells them exactly which published issues to try first. Removing it costs one configuration line and does not fix anything underneath.
The difference a version makes
| Header value | What it gives away |
|---|---|
Server: nginx | The software. Marginal. |
Server: nginx/1.18.0 | The exact release, and therefore its published issues |
X-Powered-By: PHP/7.4.3 | Runtime and version — and 7.4 has been unsupported for some time |
X-Generator: Drupal 9 (https://www.drupal.org) | CMS and major version |
X-AspNet-Version: 4.0.30319 | Framework version, and by inference the platform beneath it |
The second row is the meaningful one. Mass exploitation works by scanning for a fingerprint and firing a matching payload, and a precise version makes your site cheap to classify. Removing it does not make you safe; it makes you unclassifiable at a glance, which moves you out of the cheapest bucket of targets.
What else discloses the same thing
Removing one header while leaving five equivalents is common and pointless. The full set worth auditing:
Server,X-Powered-By,X-AspNet-Version,X-Generator.<meta name="generator">in the HTML, which often carries a full version string.- Version query strings on assets —
style.css?ver=5.8.1is a CMS version in plain sight. - Default error pages, which are branded and versioned by the software that produced them.
- Directory listings and default installation paths left reachable.
Server header while every stylesheet carries ?ver= has not hidden anything — and this is the default behaviour of several popular content management systems.Removing it
| Stack | Configuration |
|---|---|
| nginx | server_tokens off; — reduces to nginx with no version |
| Apache | ServerTokens Prod and ServerSignature Off |
| PHP | expose_php = Off in php.ini |
| Express | app.disable('x-powered-by') |
| IIS | Remove the X-Powered-By custom header; strip X-AspNet-Version |
| Behind a CDN | Most edges can strip or rewrite response headers — often the simplest place to do it |
Nothing depends on these headers. They are informational, and removing them has no functional consequence.
Keeping the right perspective
This is worth doing and it is not a security control. It is the removal of a free advantage, which is different from adding a defence.
- It does not protect an unpatched system. Attackers frequently do not check the version at all — they fire the exploit and see what happens. Patching is the control; hiding is hygiene.
- Fingerprinting works without headers. Cookie names, asset paths, error page wording and response quirks all identify a platform. You are removing precision, not identifiability.
- Order of operations matters. Patch, then stop announcing. Hiding the version of an old and vulnerable install is decorating the problem.
Checking yourself
curl -sI https://example.com | grep -iE 'server|x-powered-by|x-aspnet|x-generator'
curl -sL https://example.com | grep -i '<meta name="generator"'
curl -sL https://example.com | grep -oE '\?ver=[0-9.]+' | sort -uThe third command is the one that most often finds something after someone believes they have finished.
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, and specifically whether a version number is present.
- Whether a generator meta tag or version-stamped asset URLs disclose the platform version in the HTML.
- Platform and framework identification from all available fingerprints, labelled as inferred rather than measured.
- Whether default error pages or directory listings are reachable and identifiable.
For agents and scripts, the same measurement is at
/api/v1/security?url=yoursite.com —
see the API documentation.
Related questions
Is hiding version numbers security through obscurity?
It is obscurity, and it is worth doing anyway — it is free and it removes an advantage. The mistake is treating it as a substitute for patching rather than as a complement to it.
Does removing these headers break anything?
No. They are informational and nothing depends on them. This is one of the few changes with a real benefit and no functional cost.
What if my CDN adds its own headers?
Most edges disclose their presence, which is unavoidable and low-risk — knowing you use a particular CDN does not narrow an attack. It is your origin software version that matters, and the CDN is often the easiest place to strip it.
Should I send a fake version?
No. It provides no protection against anyone who fires exploits blindly, and it makes your own debugging and monitoring less trustworthy. Send nothing rather than something false.
Read next
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.
ReadWhat HTTP headers should every website send?
A prioritised list of response headers, what each one prevents, and which are safe to add without testing.
ReadWhat are security headers and which do I need?
Six headers, what each actually prevents, and a configuration you can paste and adjust.
ReadHow do I prove my website is secure?
What you can honestly demonstrate about your site's security, what nobody can prove, and how to make the claim checkable.
Read