How to prevent version information from leaking?
version-information-leaking global
The issue
A version number in a response turns an attacker’s guesswork into a lookup: Server: nginx/1.18.0 maps straight to published vulnerabilities for that release. The site gains nothing from announcing it.
The cause is defaults across several layers. Servers put versions in Server, frameworks add their own headers, default error pages print stack traces, and CMS platforms add generator meta tags.
Scope
Versions leak from headers, error pages, HTML comments, generator meta tags and asset URLs. Probeo’s header checks flag a Server value containing a version number, and headers that expose a framework version, such as X-Powered-By, X-AspNet-Version and X-Nuxt-Version.
How to check you have it
- In probeo: a versioned
Serverheader is recorded asheader:server, and each version-bearing header asheader:<name>, for exampleheader:x-aspnet-version. - By hand: run
curl -sI https://example.com/on a page and on a URL that returns 404, then search the page source forgeneratorand for version strings in comments.
The fix
Remove version numbers from headers, error pages and page source.
Set server_tokens off in nginx, or ServerTokens Prod in Apache. Turn off framework version headers in the application’s configuration. Replace default error pages with custom ones that show no stack trace. Strip generator meta tags and build comments from HTML output.
Done when: no header, error page or page source names a software version, and the check above comes back clean.
Do not
- Do not treat hiding versions as a substitute for patching.
- Do not remove the version tracking your own deployment and monitoring rely on.
- Do not overlook error pages and HTML comments.
FAQ
What are the most common sources of version leaks?
Server and X-Powered-By headers are the most obvious. Default error pages with stack traces are highly revealing. CMS platforms add generator meta tags by default. JavaScript framework files include version comments. HTML comments from build tools often contain timestamps and version strings. API responses sometimes include version in JSON. Each source requires specific remediation. Start with headers and error pages as highest priority.
How do attackers use version information?
They query vulnerability databases like CVE and Exploit-DB filtering by software and version. They download proof-of-concept exploit code for that version. They run automated tools that parse version strings and report known vulnerabilities. They prioritize targets running versions with critical exploits. Version disclosure converts reconnaissance from guessing to lookup. This saves attacker time and increases exploitation likelihood.
Should internal version tracking be affected?
No. Internal version tracking for deployment and debugging should continue. The distinction is between internal visibility and external disclosure. Log files, internal dashboards, and deployment systems should track versions. Public HTTP responses should not. Use separate mechanisms for internal tracking that do not leak to external observers. The goal is preventing unauthorized version enumeration not eliminating version awareness.
What about version strings in URLs or file names?
Cache-busting URL parameters like app.js?v=1.2.3 leak version information. Consider using content hashes instead like app.abc123.js where the hash changes with content. This provides cache busting without revealing version numbers. File paths like /static/v2.3/ also leak versions. Use generic paths or content-addressed naming. The functional requirement is cache invalidation not version announcement. Content hashing satisfies this without disclosure.
Can version suppression break monitoring or security tools?
Some vulnerability scanners rely on version detection. These tools may report inability to determine version rather than specific findings. Internal security tools should have privileged access to version data through APIs or configuration files rather than parsing public responses. Monitoring systems that track deployed versions should query internal services. External version disclosure is not required for internal tooling.
What if third-party libraries inject version information?
Review third-party integrations for version disclosure. JavaScript libraries loaded from CDNs often include version in filenames and comments. Load libraries from self-hosted URLs without version strings. Minification sometimes removes version comments. Self-hosting with content-hashed file names keeps the version out of the URL.
Which product detects this
Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.