Hiding Server Information in .htaccess
Every piece of information your server reveals about itself gives attackers a head start. When a response header announces that you are running Apache 2.4.51 with PHP 7.4.3, an attacker does not need to guess what software you use. They can look up known vulnerabilities for those exact versions and craft targeted exploits. While hiding server information is not a security solution on its own, it is a simple and effective layer of defense that removes low-hanging fruit from automated scanners and opportunistic attackers.
This guide covers why information disclosure matters, how to disable the TRACE HTTP method, how to remove revealing response headers like X-Powered-By, how to suppress the server signature from error pages, and how to strip potentially sensitive data from ETag headers.
Why Information Disclosure Matters
By default, Apache and the technologies running on it are surprisingly talkative about their identity. A typical response from an unconfigured server might include:
HTTP/1.1 200 OK
Server: Apache/2.4.57 (Ubuntu)
X-Powered-By: PHP/8.2.7
ETag: "1a2b3c-4d5e-5f6a7b8c9d0e"
And an error page footer might display:
Apache/2.4.57 (Ubuntu) Server at example.com Port 443
From these few lines, an attacker learns:
| Information Revealed | How It Helps an Attacker |
|---|---|
| Apache version (2.4.57) | Search CVE databases for known vulnerabilities in this version |
| Operating system (Ubuntu) | Narrow down OS-specific exploits and default configurations |
| PHP version (8.2.7) | Look up PHP-specific vulnerabilities for this exact version |
| ETag with inode data | Potentially fingerprint the server or detect load balancer changes |
| Server port | Confirm which ports are open and serving content |
Automated scanning tools like Shodan, Censys, and Nikto harvest this information at scale. They continuously crawl the internet, catalog server versions, and match them against known vulnerability databases. If your server advertises an outdated Apache or PHP version, it will appear in search results for anyone looking for vulnerable targets.
The principle here is security through obscurity as a layer, not a strategy. Hiding version information does not fix vulnerabilities. You must still keep your software updated. But removing these details forces attackers to spend more time probing, which makes automated attacks less effective and reduces your exposure to opportunistic scanning.
Disabling the TRACE Method
The HTTP TRACE method is a diagnostic tool that echoes back the exact request the server received. While this is useful for debugging proxies and intermediate servers, it creates a security risk called Cross-Site Tracing (XST).
What TRACE Does
When a client sends a TRACE request:
TRACE / HTTP/1.1
Host: example.com
Cookie: session=abc123
Authorization: Bearer token-xyz
The server responds with the entire request reflected back in the response body:
HTTP/1.1 200 OK
Content-Type: message/http
TRACE / HTTP/1.1
Host: example.com
Cookie: session=abc123
Authorization: Bearer token-xyz
An attacker who can trick a user's browser into sending a TRACE request (via Java applets, Flash, or other mechanisms) can read the reflected response and steal authentication cookies and tokens, even if those cookies are marked as HttpOnly (which normally prevents JavaScript from reading them).
Modern browsers block TRACE requests initiated by JavaScript (XMLHttpRequest and fetch), but other attack vectors exist through browser plugins and less common HTTP clients.
Blocking TRACE with a RewriteRule
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^TRACE [NC]
RewriteRule .* - [R=405,L]
</IfModule>
This configuration:
RewriteCond %{REQUEST_METHOD} ^TRACE [NC]matches any request using theTRACEmethod (case-insensitive).RewriteRule .* - [R=405,L]returns a 405 Method Not Allowed response for any URL. The-means no URL substitution. The[L]flag stops further processing.
After adding this rule, a TRACE request receives:
HTTP/1.1 405 Method Not Allowed
Verifying the Block
You can test this with curl:
curl -X TRACE https://example.com/
Without protection, you see the request echoed back. With the rule in place, you receive a 405 error.
If you have access to the main Apache server configuration (httpd.conf or a virtual host file), the cleaner approach is to use the TraceEnable directive:
# In httpd.conf or virtual host config (not available in .htaccess)
TraceEnable Off
This disables TRACE at the server level, which is more efficient than processing it through mod_rewrite. The .htaccess rewrite approach is the alternative when you do not have access to the main configuration.
Also Consider Blocking TRACK
The TRACK method is a non-standard equivalent of TRACE that some servers support. Block both for completeness:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) [NC]
RewriteRule .* - [R=405,L]
</IfModule>