Server Information Hiding: Preventing Version Exposure and Customizing Error Pages
When server software version information is exposed externally, it becomes easier for attackers to find and exploit known vulnerabilities. Minimize server information exposure by removing version information and customizing error pages.
Nginx Server Information Hidingβ
Disabling server_tokensβ
# /etc/nginx/nginx.conf β http block
http {
# Response header: Server: nginx/1.24.0 β Server: nginx
server_tokens off;
}
# Before applying: Server: nginx/1.24.0
curl -I https://example.com | grep Server
# Server: nginx/1.24.0
# After applying: Server: nginx
curl -I https://example.com | grep Server
# Server: nginx
# Complete removal (requires nginx-extras or OpenResty)
# more_clear_headers Server;
Complete Removal or Modification of Server Headerβ
# headers-more module available when nginx-extras package is installed
# sudo apt install nginx-extras
http {
server_tokens off;
# Change Server header content
more_set_headers 'Server: WebServer';
# Or completely remove
more_clear_headers 'Server';
more_clear_headers 'X-Powered-By';
}
Apache Server Information Hidingβ
# /etc/apache2/conf-available/security.conf or apache2.conf
# Remove Apache version from response headers
# Full: Apache/2.4.41 (Ubuntu)
# Prod: Apache (no version)
# Min: Apache
ServerTokens Prod
# Disable server signature (shown at bottom of error pages)
ServerSignature Off
# Remove X-Powered-By header
Header unset X-Powered-By
# Remove inode information from ETag header (prevent information exposure)
FileETag MTime Size
sudo a2enconf security
sudo systemctl reload apache2
PHP/Tomcat Information Hidingβ
Remove PHP X-Powered-Byβ
# /etc/php/8.x/fpm/php.ini or apache2/php.ini
expose_php = Off
# X-Powered-By: PHP/8.1.0 β header removed
Remove Tomcat Server Informationβ
<!-- conf/server.xml -->
<!-- Remove server attribute from Connector -->
<Connector port="8080"
protocol="HTTP/1.1"
server="" β Empty string removes Server header
/>
// Customize Server header in Spring Boot
@Configuration
public class TomcatConfig {
@Bean
public TomcatServletWebServerFactory tomcatFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(connector -> {
connector.setProperty("server", ""); // Remove Server header
});
return factory;
}
}
Custom Error Page Configurationβ
Default error pages contain server version information. Replace them with custom error pages.
Nginx Custom Error Pagesβ
server {
# Error page mapping
error_page 400 /errors/400.html;
error_page 401 /errors/401.html;
error_page 403 /errors/403.html;
error_page 404 /errors/404.html;
error_page 500 502 503 504 /errors/500.html;
# Error page file location
location ^~ /errors/ {
root /var/www;
internal; # Not accessible directly from outside
}
# JSON API servers return JSON error responses
location /api/ {
error_page 404 @api_not_found;
error_page 500 @api_error;
proxy_pass http://backend;
}
location @api_not_found {
add_header Content-Type "application/json" always;
return 404 '{"error":"Not Found","code":404}';
}
location @api_error {
add_header Content-Type "application/json" always;
return 500 '{"error":"Internal Server Error","code":500}';
}
}
Error page example (/var/www/errors/404.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404 - Page Not Found</title>
<style>
body { font-family: sans-serif; text-align: center; padding: 50px; }
h1 { color: #333; }
</style>
</head>
<body>
<h1>Page Not Found</h1>
<p>The page you requested does not exist.</p>
<a href="/">Return to Home</a>
<!-- No server version information -->
</body>
</html>
Apache Custom Error Pagesβ
# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:443>
# Error page configuration
ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html
# Error page directory
Alias /errors/ /var/www/errors/
<Directory /var/www/errors/>
Require all granted
Options -Indexes
</Directory>
</VirtualHost>
Disabling Directory Listingβ
# Nginx β disabled by default (autoindex off is default)
location /files/ {
autoindex off; # Explicitly disable
alias /var/www/files/;
}
# Apache β enabled by default, must explicitly disable
<Directory /var/www/html>
Options -Indexes -FollowSymLinks # Remove Indexes
AllowOverride None
</Directory>
Blocking Access to Sensitive Filesβ
# Block hidden files (.env, .git, .htpasswd, etc.)
location ~ /\. {
deny all;
return 404;
}
# Block direct access to configuration files
location ~* \.(env|conf|config|bak|backup|sql|log)$ {
deny all;
return 404;
}
# Block git directory
location ~ /\.git {
deny all;
return 404;
}
Auditing Current Security Information Exposureβ
# Check currently exposed headers
curl -sI https://example.com | grep -iE "server|x-powered|via|x-aspnet|x-generator"
# Scan for information disclosure vulnerabilities with Nikto
sudo apt install nikto
nikto -h https://example.com -Tuning 0 # Information disclosure items only
# Check error pages (verify server information exposure)
curl -s https://example.com/nonexistent-page-xyz | grep -i "nginx\|apache\|tomcat\|version"