How to remove framework and server headers?
framework-headers-present global
The issue
A response that names its framework and server, often with a version, hands attackers the first step of reconnaissance. With X-Powered-By: Express or Server: nginx/1.18.0, they can look up known flaws for that exact software instead of probing for them. The headers do nothing for browsers.
The cause is defaults. Many servers, frameworks and platforms add these headers unless told not to, and each layer, from application to proxy to CDN, can add its own.
Scope
The headers are checked on each response probeo fetches. Probeo flags headers that expose a framework version or internal identifiers, such as X-Powered-By, X-AspNet-Version, X-AspNetMvc-Version, X-Runtime and X-Generator. It flags Server only when its value carries a version number or a private host name.
How to check you have it
- In probeo: each header is recorded as
header:<name>, for exampleheader:x-powered-byorheader:x-aspnet-version. A versionedServeris recorded asheader:server, and one naming a private host asserver:private-host-exposure. - By hand: run
curl -sI https://example.com/and read the headers. Check an error page too, such as a URL that returns 404.
The fix
Turn off the identifying headers at each layer that adds them.
In Express, call app.disable('x-powered-by'). In nginx, set server_tokens off. In Apache, set ServerTokens Prod and ServerSignature Off. In ASP.NET, set enableVersionHeader="false" on httpRuntime. Then check what the CDN or proxy adds on top.
Done when: no response names its framework, and no Server header carries a version, and the check above comes back clean.
Do not
- Do not replace the headers with false values; misdirection adds work and no protection.
- Do not remove security headers such as
Content-Security-Policyalong with them. - Do not check only successful responses; error pages often carry more.
- Do not treat removal as a substitute for patching.
FAQ
Does removing headers actually improve security?
It reduces information available to attackers. This is defense in depth not complete protection. Determined attackers can fingerprint implementations through response timing, error messages, and behavior patterns. Header removal increases reconnaissance cost without guaranteeing anonymity. It should accompany not replace vulnerability patching and security controls. The low cost of header removal makes it worthwhile despite limitations.
What should the Server header contain if not removed entirely?
Generic values like Server: WebServer, or omit it entirely. Use values that do not identify specific software. Do not include version numbers. The goal is reducing information not misdirection. False headers like Server: Apache when using nginx waste effort and provide no benefit. Generic or absent is sufficient.
Can attackers still identify frameworks without headers?
Often yes. Response structure, cookie names, URL patterns, and default error messages leak framework information. A Django site’s CSRF token format reveals Django. Ruby on Rails has characteristic URL conventions. Complete fingerprinting prevention requires broader efforts. Header removal handles the easiest and most blatant disclosure. Combine with custom error pages, cookie renaming, and eliminating framework-specific patterns for deeper protection.
What if the CDN adds its own Server header?
Configure the CDN to suppress or replace the header. Most CDNs allow header manipulation. Set the CDN to remove origin Server headers and not add its own. Some CDNs add headers identifying themselves like Server: cloudflare. These reveal CDN provider but not origin implementation. If CDN headers cannot be removed, focus on removing application-specific headers like X-Powered-By which are more revealing.
Should error responses also have headers removed?
Yes especially error responses. Default error pages often include framework version in stack traces or error messages. 500 errors may expose server software through default error formats. 404 pages sometimes include server signatures. Configure custom error pages that do not include implementation details. Verify header removal on error responses not just successful responses. Errors often reveal more than normal operation.
What about X-Frame-Options and other security headers?
Security headers should be present. The distinction is between headers that protect versus headers that disclose. X-Frame-Options, Content-Security-Policy, and X-Content-Type-Options enhance security. X-Powered-By, Server version info, and X-AspNet-Version disclose information. Remove disclosure headers while adding protective headers. These goals are compatible and should both be pursued.
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.