Information disclosure vulnerabilities rarely enable direct exploitation on their own. Their value is in what they tell an attacker about the target: which software is running, which version, which framework, how the application is structured internally. This information reduces the effort required to find and exploit a higher-severity vulnerability because the attacker can focus on known weaknesses in the identified software rather than probing blindly.
This article covers the disclosure patterns most commonly found in HTTP responses, the reconnaissance value each provides, and how to suppress them.
Why Information Disclosure Matters
A server that reveals it is running nginx 1.18.0 on Ubuntu 20.04 with PHP 7.4.3 and WordPress 6.1.1 has told an attacker which known vulnerabilities apply, which public exploits are available, and which configuration patterns to attempt. The attacker does not need to fingerprint the server through behavior; the server announced itself.
Individually, each disclosed piece of information has limited value. Combined, they create a precise target profile. The correct position is to disclose nothing that is not required for the application to function. Version numbers, framework identifiers, and internal infrastructure details are never required.
Server Version Headers
The Server HTTP response header is set by the web server software and typically includes both the software name and the version number. Many default configurations produce headers like:
Server: nginx/1.18.0 (Ubuntu)
Server: Apache/2.4.51 (Debian) OpenSSL/1.1.1k PHP/7.4.3
Server: Microsoft-IIS/10.0The software name alone (nginx, Apache) has limited value since it can often be inferred from other signals. The version number is what enables targeted attacks: an attacker who knows the exact version can cross-reference it against CVE databases to identify unpatched vulnerabilities.
The Server header should be suppressed or replaced with a generic value that does not reveal version information.
X-Powered-By and Framework Headers
The X-Powered-By header is set by application frameworks and language runtimes, typically without the application developer's explicit configuration. Common examples:
X-Powered-By: PHP/8.1.12
X-Powered-By: Express
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 5.2For PHP, the version number is particularly useful because PHP versions have well-documented vulnerability histories and end-of-life dates. Running PHP 7.4 (EOL as of November 2022) is a significant finding; announcing it in every response is an avoidable amplification.
Debug and Internal Headers
Debug and tracing headers are added by application frameworks, APM tools, and development middleware. They are intended for development and debugging environments but sometimes reach production:
X-Debug-TokenandX-Debug-Token-Link: Added by Symfony's profiler toolbar. The debug token link points to a detailed profiler page showing request data, SQL queries, security context, and application configuration.X-Runtime: Added by Rails. Shows the server-side execution time in milliseconds, which leaks framework identity and can assist timing-based inference.X-Generator: Added by some CMS platforms revealing the generator and version.Liferay-Portal: Added by Liferay portal deployments.
The Symfony profiler link (X-Debug-Token-Link) is particularly high impact. Visiting the linked URL on a development server exposes the complete request context including POST data, session variables, security tokens, and database queries. If the profiler is enabled in production (it should never be), this is a direct data exposure.
Stack Traces in Error Pages
When an unhandled exception reaches the user-facing error response, the stack trace exposes the application's internal structure: file paths, class names, method names, and frequently database query strings or SQL error messages. A stack trace from a Java application might reveal:
java.sql.SQLException: Table 'app_production.users' doesn't exist
at com.example.app.dao.UserRepository.findById(UserRepository.java:47)
at com.example.app.service.UserService.getUser(UserService.java:83)
at com.example.app.controller.UserController.profile(UserController.java:31)
...This reveals: the database name (app_production), the table name (users), the full package structure, and the exact file and line numbers involved. Combined with other signals, this can confirm the presence of SQL injection by identifying which queries are being constructed.
Error handling must be configured to return generic error pages to users in production. The full error detail should be logged server-side where it is accessible only to the development team.
Internal IP Addresses in Responses
Internal IP addresses appear in responses through several mechanisms: misconfigured reverse proxy setups that forward internal X-Forwarded-For or Via headers, application code that includes server addresses in API responses, and error messages that reference internal hostnames.
A response containing X-Forwarded-For: 10.0.1.15 or Via: 1.1 internal-lb-001.example.internal reveals the internal network addressing scheme and infrastructure topology. This information assists attackers who have achieved partial network access (SSRF, VPN compromise) in understanding how to pivot within the internal network.
Sensitive HTML Comments
HTML comments left in production pages from development and debugging are another consistent information disclosure source. Common patterns:
<!-- TODO: remove before production, admin password is temp123 -->
<!-- DEBUG: user_id=1847, role=admin, session_token=abc123... -->
<!-- v2.3.1 deployed 2026-01-15 by jenkins@ci-server -->
<!-- Database connection: mysql://app:password@10.0.1.5/production -->HTML comments are visible to any user who views the page source. They are frequently added during development and never removed because developers do not expect end users to read source code. Template engines that compile templates at build time may include comments from included partials that the developer never directly views.
CMS Generator Meta Tags
Content management systems often add a <meta name="generator"> tag to page HTML containing the CMS name and version:
<meta name="generator" content="WordPress 6.1.1" />
<meta name="generator" content="Drupal 9 (https://www.drupal.org)" />
<meta name="generator" content="Joomla! - Open Source Content Management" />For WordPress sites in particular, the generator meta tag provides the exact version, which can be cross-referenced against the WordPress vulnerability database to identify known unpatched issues.
Remediation by Server Type
Suppress version disclosure in nginx:
# nginx.conf
http {
server_tokens off; # removes version from Server header and error pages
}Suppress version disclosure in Apache:
# httpd.conf or .htaccess
ServerTokens Prod # show "Apache" only, no version
ServerSignature Off # remove server info from error pagesRemove X-Powered-By in PHP:
; php.ini
expose_php = OffRemove X-Powered-By in Express:
app.disable('x-powered-by');
// or use helmet.js which hides it by default:
const helmet = require('helmet');
app.use(helmet());Remove the WordPress generator meta tag:
// In functions.php
remove_action('wp_head', 'wp_generator');How WebDefect Identifies Information Disclosure
WebDefect checks for information disclosure in both HTTP headers and response body content across all discovered pages. The checks include:
- Server version header (
hdr-005): TheServerheader contains a version number. Low severity. - X-Powered-By header (
hdr-006): Any value inX-Powered-By,X-AspNet-Version, or similar technology disclosure headers. Low severity. - Debug headers (
info-004): Known debug headers such asX-Debug-Token,X-Debug-Token-Link,X-Runtime,X-Generator. Low to medium severity depending on the specific header. - Internal IP in response (
info-001): RFC 1918 addresses (10.x.x.x, 172.16-31.x.x, 192.168.x.x) or loopback addresses in response headers or body. Low severity. - Stack trace in error response (
err-001): Response bodies matching stack trace patterns for Java, Python, PHP, Ruby on Rails, ASP.NET, or Node.js. Medium severity. - CMS meta generator tag (
info-003): The<meta name="generator">tag with CMS version information. Low severity. - Sensitive HTML comments (
info-002): HTML comments containing patterns such as credentials, IP addresses, internal paths, or version identifiers. Low severity.