Skip to main content

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"