Skip to content
GDPR compliant. Hosted in DE.
14-day free trial →
Information disclosureHeader hardeningSecurity scan
Security 13 min read 6 Sept 2026

Turn Off Version Banners: What Your Headers Reveal

Server, X-Powered-By, X-AspNet-Version: response headers name product and version. What the disclosure causes, which setting helps and what stays visible afterwards.

X

XICTRAQ

XICTRAQ

Information disclosureServer headerSecurity-Scan
91.5 %
of hosts on the web send a Server header in their response (Web Almanac 2025)
27 %
and more of all X-Powered-By headers contain version information (Web Almanac 2025)
2nd rank
for Security Misconfiguration in the OWASP Top 10:2025, up from rank 5 (OWASP)
What response headers give away - and which setting takes effectResponse headers before trimmingOne request, no login, no exposed fileHTTP/2 200server: Apache/2.4.52 (Ubuntu)x-powered-by: PHP/7.4.33via: 1.1 proxy-0191.5 percent of hosts send a Server header23.9 percent additionally send an X-Powered-By headerSurvey: Web Almanac 2025What can be derived from itWithout any further access to the siteProduct and version of the web serverServer header, default ServerTokens FullRuntime including its version levelX-Powered-By, default expose_php = 1Branch unmaintained since 28 Nov 2022PHP 7.4.33 was the final release of that branchUpstream intermediary in the stackVia header from the caching layerMisconfiguration: rank 2 in the OWASP Top 10:2025ServerTokens ProdApache HTTP Server, default: FullResponse names the product onlyServerSignature Off for error pagesserver_tokens offnginx, default: onVersion drops from header and error pagealso applies to the body of 4xx pagesexpose_php = OffPHP, default: 1X-Powered-By disappears entirelytakes effect after the runtime restartsRecurring header checks, history per domain, alert on relapseProcessing and hosting in Germany - built into XICTRAQTrimming lowers discoverability, not exploitability - the version in use remains the real task
Every response a web server sends carries a small business card. It is not on the page but above it, in the response headers: "server: Apache/2.4.52 (Ubuntu)", followed by "x-powered-by: PHP/7.4.33". That is not a breach and not a vulnerability, it is a default - one that still leaves a Server header on 91.5 percent of hosts on the web and an X-Powered-By header on another 23.9 percent (Web Almanac 2025). The article on forgotten files in the web root lists reading these headers as one check point among several. Here the signature itself takes centre stage: the line that turns a site into a hit for an automated sweep without a single exposed file. This guide shows what a version banner actually contains, how widespread the disclosure is, which setting takes effect on which layer, what switching it off explicitly does not achieve and how to keep the result in place instead of losing it with the next package upgrade.

What a version banner actually contains

The term comes from network diagnostics: a service announces who it is on first contact. On the web that self-description sits in the response headers. The OWASP testing guide calls collecting it banner grabbing and keeps the effort short: an HTTP request is sent to the web server and its response header is examined (OWASP Testing Guide). No account, no privileged tooling, no exploited weakness - one request is enough, and the answer comes from the public page itself. That is exactly why the item appears early in test catalogues: it costs the tester a second and may cost the operator the pre-selection that an attack starts from.

  • Server: product name, often the exact version, sometimes the distribution and the modules compiled in.
  • X-Powered-By: the runtime behind the application, as a rule including its version number.
  • X-AspNet-Version and X-AspNetMvc-Version: the framework version, independent of the web server in front of it.
  • X-Server and X-Backend-Server: internal host names that expose the naming scheme of your own environment.
  • Via and X-Cache: upstream intermediaries including their product - visible even when the origin server stays silent.
  • Error pages: a web server's default page names product and version in its footer, even when the header has long been trimmed.

In the weakness taxonomy the finding has a class of its own. CWE-200 describes a product exposing sensitive information to an actor that is not explicitly authorised to access it (MITRE CWE). The information types listed there include system status and environment such as the operating system and installed packages - precisely what a version banner delivers without a detour. The classification is deliberately broad: it describes no exploitable hole but the stage before one. For internal assessment that difference is useful, because it determines the urgency the item is treated with.

How widespread the disclosure is

The Web Almanac evaluates responses from millions of hosts and has tracked informational headers across several editions. For 2025: these headers show up on 91.5 percent and 23.9 percent of hosts on the web (Web Almanac 2025) - meaning Server and X-Powered-By. Across three editions the curve points slightly downwards, but the movement is small. The report also gives the reason: many web technologies set some of these headers automatically, and the security gain from removing them appears small (Web Almanac 2025). The overview below sorts the fields by what they reveal about the stack behind them.

HeaderTypical contentPrevalence 2025What it reveals
ServerApache/2.4.52 (Ubuntu)91.5 percent of hostsproduct, usually version, often the distribution
X-Powered-ByPHP/7.4.3323.9 percent of hostsruntime including its version level
X-AspNet-Version4.0.30319far less commonframework version
X-Server, X-Backend-Serverweb-03.internalfar less commoninternal naming scheme, number of nodes
Via, X-Cache1.1 proxy-01, HITvariesupstream caches and their product
Error page without headerfooter carrying the product nameindependent of the headernames the server when the header stays quiet

The values themselves are where it gets interesting. Among X-Powered-By entries carrying a concrete version, PHP/7.4.33 leads the field: 9.54 percent on desktop and 9.98 percent on mobile (Web Almanac 2025). Across both data sets more than 27 percent of X-Powered-By headers contain version information (Web Almanac 2025). The 7.4 branch has been unmaintained since 28 November 2022, and 7.4.33 was its final release (PHP Manual). Anyone reading that string in a response knows not only the product but also that no security release has appeared for this branch in years. The manual itself urges an upgrade to a current version, because older versions remain open to vulnerabilities and bugs that have since been fixed (PHP Manual).

The line is an indication, not proof

A header can be faked, trimmed or replaced by an upstream service - the value on display need not match the version actually running. Its absence proves little either: the testing guide notes that the type of server can be guessed from the ordering of the header fields even when the server information is obscured (OWASP Testing Guide). Concluding from a trimmed header that your environment is no longer identifiable mistakes a hurdle for a wall. For your own inventory that means the header is a pointer for clean-up work, not a measure of security posture.

Why a version string attracts automated sweeps

The Web Almanac justifies the measurement with a sentence that captures the chain of effects well: when websites publish excessive information about their infrastructure, such as the server and its specific version, they may run a higher risk of being targeted by automatic vulnerability scanners (Web Almanac 2025). Against that stands the sober note in the server documentation that disabling the Server header does nothing at all to make your server more secure (Apache HTTP Server). Together those two statements set a realistic expectation: the benefit lies in the pre-selection, not in protection. Four mechanisms explain why the pre-selection still matters.

Pre-selection instead of full testing

A sweep across thousands of addresses first sorts by traits available at no cost. A version number in the header is exactly such a trait: it answers the question of which route fits before the first real probe runs, shifting compute from reconnaissance to attempt.

The window after disclosure

Between the publication of a vulnerability and the applied update lies a window. Anyone stating the affected version in plain text during that period is on the shortest list. How to follow new entries in an orderly way is covered in the article on vulnerability feeds.

The chain of several lines

The information rarely sits in a single header. Web server, runtime, application framework and upstream cache each announce themselves separately. Combined they yield a picture of the stack more precise than any single entry - including how many nodes sit behind it.

A risk category of its own

Misconfiguration is no footnote in the OWASP Top 10:2025: the category moved up from #5 to #2 (OWASP). It bundles 16 weakness classes with 719,084 occurrences in total and 1,375 entries from the vulnerability database (OWASP).

The numbers behind the category are clear: in the analysis of Security Misconfiguration every application tested was found to have some form of misconfiguration, at an average incidence rate of 3.00 percent (OWASP). A version string in a header is the most harmless member of that family - and at the same time the most visible one, because it can be read from outside without any login. Anyone working through the OWASP Top 10:2025 overview finds the category directly behind broken access control, a position rarely skipped in audit reports.

What the standard says - and what it does not promise

The Server header is described in RFC 9110, the standard for HTTP semantics. It contains no demand to drop the header, but it does contain one to keep it short: an origin server should not generate a Server header field containing needlessly fine-grained detail and should limit the addition of subproducts by third parties (RFC 9110). The reasoning follows in the same section: overly long and detailed Server field values increase response latency and potentially reveal internal implementation details that might make it slightly easier for attackers to find and exploit known security holes (RFC 9110). The standard thus draws a line between disclosure and over-disclosure - and puts it at the version number.

In theory, this can make it easier for an attacker to exploit known security holes; in practice, attackers tend to try all potential holes regardless of the apparent software versions being used.

— RFC 9110, Section 17.12

The second half matters more, because it sets expectations. The Apache HTTP Server documentation is blunter still at the same point: disabling the Server header does nothing at all to make your server more secure (Apache HTTP Server). Neither statement contradicts the advice to trim the banner - they put its value in perspective. The German federal office for information security nonetheless states the requirement for web servers narrowly and without qualification: neither the product name nor the version of the web server in use should be visible from the HTTP information or from displayed error messages (BSI). Between those poles lies the practical answer: trim it, because it costs little, and patch it, because only that shrinks the attack surface.

Trimming is no substitute for patching

A trimmed header changes nothing about the version that actually answers. Removing the line while leaving the branch in place lowers visibility and keeps the risk - and makes your own inventory harder, because the stack is now less readable from outside. The order is therefore: first the patch level of the software in use, then the signature, and both documented. How to find outdated building blocks on the page itself is covered in the article on vulnerable JavaScript libraries.

The settings on each layer

The defaults speak for themselves. On the Apache HTTP Server the default for the ServerTokens directive is simply Full (Apache HTTP Server) - the response then names product, version, operating system type and compiled-in modules in a single line. On nginx, server_tokens defaults to on (nginx); the directive enables or disables emitting the nginx version on error pages and in the Server response header field (nginx). And PHP sets expose_php to 1 by default, which exposes to the world that PHP is installed on the server, including the PHP version within the HTTP header (PHP Manual). Three defaults, three lines in the response - without anyone having configured them.

LayerSettingDefaultEffect
Web server, Apache variantServerTokens Prod, ServerSignature OffServerTokens Fullresponse names the product only, error page without signature line
Web server, nginx variantserver_tokens offserver_tokens onversion disappears from header and error pages at once
PHP runtimeexpose_php = Offexpose_php = 1X-Powered-By drops entirely, takes effect after a restart
Application frameworkremove framework headersframework dependentX-AspNet-Version, X-Generator and similar disappear
Upstream serviceoverwrite or strip headerspass throughVia, X-Cache and backend names no longer reach the visitor
Error and redirect pagesown pages without product namesthe product's default pagethe footer no longer names the server

The order of changes is not arbitrary. An upstream service can add, overwrite or pass through headers unchanged; touching only the origin server may leave you with the same response as before. Hence the simple rule: measure from outside, do not read the configuration file. The response at the public address is the only authority that counts, and it regularly differs from what the repository says. Three calls are enough for the counter-check - one before the change, one against an address that does not exist and one afterwards.

$ curl -sI https://example-domain.com/ | grep -iE 'server|x-powered|x-aspnet|via'
server: Apache/2.4.52 (Ubuntu) x-powered-by: PHP/7.4.33 via: 1.1 proxy-01
$ curl -s https://example-domain.com/this-page-does-not-exist | tail -n 2
Apache/2.4.52 (Ubuntu) Server at example-domain.com Port 443
$ curl -sI https://example-domain.com/ | grep -iE 'server|x-powered|x-aspnet|via'
server: Apache
$ curl -s https://example-domain.com/this-page-does-not-exist | tail -n 2
(custom error page, no product and no version information)

Two points are frequently overlooked. First the error pages: a web server's default page names the product in its footer even when the header has already been trimmed. On the Apache HTTP Server, ServerSignature controls that line; on nginx, server_tokens affects header and error pages at once (nginx). Second, the response types rarely requested by hand: redirects, status 404 and status 500 often come from a different layer than the home page and stay untouched by the change. Both belong in the same check as the header - and they complement the overview of security headers, which covers the opposite direction: what a response should additionally contain.

What stays visible after switching off

An empty Server header does not make an environment unrecognisable. The testing guide names the simplest remaining route: where the server information is obscured, the type of server can be guessed from the ordering of the header fields (OWASP Testing Guide). Beyond that, plenty of traits remain that no switch turns off, because they come from the implementation itself rather than from a configuration line.

  • Ordering and spelling of the header fields differ by product and persist even when the values themselves give nothing away.
  • Structure of the error pages, wording of status messages and the handling of unusual requests are product specific and hard to normalise.
  • Names and structure of session cookies point to the runtime; which attributes belong there anyway is covered in the article on secure session cookies.
  • Format of ETag values and the handling of conditional requests follow each server's implementation and can be attributed.
  • Behaviour on HTTP/2 and HTTP/3 as well as the order of cipher suites offered in the TLS handshake form another identifying trait.
  • Open services beyond the web server announce their own identifiers; an inventory of externally reachable services shows which ones exist.
Less signature is effort for the other side, not protection for the software

The honest benefit of a trimmed response fits in one sentence: it takes the cheapest sorting aid away from a broad sweep and forces it to spend more effort or move on. Against a targeted attack on a known target it does little. That is precisely why the measure belongs on the same list as removing unused endpoints and clearing out forgotten files - many small steps that achieve little alone and much together, as long as the versions in use are kept current.

Why the banner comes back

Switching it off is a task of minutes. Keeping it off is a state that has to be maintained. In practice the line returns for six recurring reasons, and in nearly every case nobody notices, because the site keeps working. That is exactly what makes this an item for recurring checks rather than for a project handover list.

  1. Package upgrade with a new default configuration: the update drops an untouched configuration file next to yours or replaces it. Your customisation ends up as a backup copy in the directory and is no longer read.
  2. An additional service in front: a new cache or balancing layer sets its own headers and writes Via or X-Cache into the response, even though the origin server has long gone quiet.
  3. A second virtual host: the change was made in the main section and the new site does not inherit it. The result is two addresses of the same organisation with two different answers.
  4. New image, old default: rebuilding the container pulls the base image fresh and starts back at the default whenever the change is not part of the build recipe.
  5. A framework upgrade brings new headers: moving to the next version of an application framework adds fields that did not exist before. How quickly versions succeed each other today is shown in the article on two-week release cycles.
  6. Rollback after an incident: restoring an older state after an incident brings the old configuration along - and with it the old signature.

Adding the header check to ongoing monitoring

An item that returns without warning and causes no visible outage is the textbook case for a recurring measurement. The check itself is cheap: one request per address, a comparison against the last known state, an alert on deviation. The only expensive part is repeating it by hand. Six steps turn it into a routine you can rely on.

  1. Record the baseline: note today's value of Server, X-Powered-By, X-AspNet-Version, Via and your own framework headers for every address. Without a baseline there is no deviation later, only a snapshot.
  2. Cover every address, not just the home page: secondary domains, redirect targets, image services and form endpoints often answer from a different layer. How to close that gap systematically is described in the article on URL inventory coverage.
  3. Include the response types: besides status 200, redirects, status 404 and status 500 belong in the run, because different layers answer there.
  4. Define the threshold: decide which change triggers an alert - a version number appearing anew should, a changed cache hit marker should not.
  5. Set up a route for outside reports: whoever discovers a disclosure needs an address to send it to. The article on security.txt and disclosure routes describes the short path there.
  6. Feed the finding into the regular review: a recurring security scan keeps the header state next to certificate lifetime, availability and content changes, so deviations surface in the same report.

The effort for that routine is small; the benefit is in the side effect. Recording response headers continuously also reveals a switched runtime, the silent introduction of an upstream service and the return of an older state after an incident. A security measure thus becomes a window onto the actual shape of your environment. Which checks run at which interval and what that costs is shown in the plan overview - header analysis is part of the recurring run rather than a separate line item.

Sources and Studies

This article draws on RFC 9110 (HTTP Semantics) from the IETF, the Web Almanac 2025 by the HTTP Archive, the OWASP Top 10:2025 and the OWASP Web Security Testing Guide. Additional references are the German BSI IT-Grundschutz compendium with module APP.3.2 Web Server, the Apache HTTP Server documentation, the nginx documentation, the PHP manual including the list of unsupported branches and the CWE-200 weakness classification by MITRE. The figures quoted refer to the state of each publication; configuration details apply to the documented version of the respective product.

What is a version banner and where does it appear?
Version banner is the term for the response headers with which a web server announces product and version on its own - above all Server and X-Powered-By, plus X-AspNet-Version, X-Server and Via. They sit above the page itself and can be read with a single request. The OWASP Web Security Testing Guide describes the procedure as banner grabbing: an HTTP request is sent and the response header examined (OWASP Testing Guide). The Server header appears on 91.5 percent of hosts on the web (Web Almanac 2025).
Does switching off the Server header really improve security?
It lowers discoverability, not exploitability. RFC 9110 notes that disclosing the version can in theory make it easier to exploit known holes, while in practice attackers try all potential holes regardless of the apparent software versions being used (RFC 9110). The Apache HTTP Server documentation puts it more bluntly: disabling the header does nothing at all to make your server more secure (Apache HTTP Server). The practical gain is dropping out of the pre-selection made by broad sweeps - and that costs little.
Which settings switch the version string off?
On the Apache HTTP Server it is ServerTokens, whose default is Full (Apache HTTP Server); the value Prod reduces the response to the product name, and ServerSignature Off removes the line from error pages. On nginx, server_tokens controls whether the version is emitted on error pages and in the Server response header field and defaults to on (nginx). In PHP, expose_php = Off removes the X-Powered-By header; the default of 1 exposes to the world that PHP is installed, including the version within the HTTP header (PHP Manual). Application frameworks and upstream services each need a rule of their own.
How do I find out what my site actually discloses?
Measure from outside, do not read the configuration file. A curl call against the public address shows the header set exactly as a visitor receives it, including additions from upstream services. It matters to check more than the home page: redirects, status 404 and status 500 often come from a different layer and keep their signature when only the main path was adjusted. The same measurement belongs on a schedule, because package upgrades bring the default back.
What remains identifiable once all headers are gone?
A whole range of traits. The OWASP Web Security Testing Guide points out that the type of server can be guessed from the ordering of the header fields where the server information is obscured (OWASP Testing Guide). Added to that are the structure of error pages, names and format of session cookies, the format of ETag values, behaviour on HTTP/2 and HTTP/3 and the order of cipher suites in the TLS handshake. Removing the headers is therefore a hurdle for automated pre-selection, not camouflage.
How urgent is this item compared with other findings?
It belongs to the misconfiguration category, which moved from #5 to #2 in the OWASP Top 10:2025 (OWASP); in that analysis every application tested was found to have some form of misconfiguration, at an average incidence rate of 3.00 percent (OWASP). Within the category the version string is the lightest case: quickly fixed, no downtime, no side effects. Missing updates and openly reachable administration areas rank ahead of it. The German BSI nonetheless requires explicitly for web servers that neither the product name nor the version should be visible from HTTP information and error messages (BSI).

Related in XICTRAQ

Start in 60 seconds

Let XICTRAQ watch your website.

Permanent free plan available. No credit card, no installation, no hidden fees.