Exposed server status page

A server status page (Apache mod_status, nginx stub_status or PHP-FPM status) is reachable from the internet, revealing live requests, client IPs, internal hostnames and load details.

Do this: Restrict the status page to localhost. It shows live request URLs, client addresses and internal paths as visitors use the site.
PassNo exposed server status page was found.
MediumA server status page is publicly reachable.

The fix, in one snippet

Example to adapt Apache
<Location "/server-status">
  Require local
</Location>

Illustrative values. Change the paths, hostnames and options to match your own site before using it.

The sections below explain what is tested, why it matters and the alternatives.

What we test

Scan.now requests /server-status, /server-status?auto and /server-info (Apache), /nginx_status, /status and /basic_status (nginx stub_status), and /fpm-status and /php-fpm-status (PHP-FPM). A finding requires a 200 response with the module's signature: "Apache Server Status for" or "Apache Status" in the title, a line matching Active connections: N for nginx, or pool: and process manager: lines for PHP-FPM. A 401 or 403 at these paths passes: the page exists but is protected. The report says which page was found and, for Apache, whether ExtendedStatus is on, which is what turns a load summary into a request-by-request log. Rated medium; an Apache extended status page is closer to high, an nginx stub_status page closer to low.

Why it matters

Apache's status page with ExtendedStatus On shows every request currently being processed: the client IP, the virtual host, the full request line including query strings, and how long each has been running. That leaks other users' activity in real time (session tokens or reset links that travel in query strings appear here), reveals internal hostnames and backend structure, and gives an attacker an instant readout of whether their probing is being slowed down. /server-info dumps the entire compiled and loaded configuration. nginx's stub_status shows only connection counts, which is mostly a capacity-planning leak. PHP-FPM's status page with full shows request URIs per worker, similar to Apache. In all cases the page also confirms the exact software in use. The exposed files guide groups this with the other debug endpoints worth locking down.

How to fix it

Restrict the pages to localhost or a monitoring network; do not just hide them behind an obscure path. Apache:

<Location "/server-status">
    SetHandler server-status
    Require local
</Location>
<Location "/server-info">
    SetHandler server-info
    Require ip 10.0.0.0/8
</Location>
# or disable entirely: a2dismod status info

nginx:

location = /nginx_status {
    stub_status;
    allow 127.0.0.1;
    allow 10.0.0.0/8;
    deny all;
}

PHP-FPM sets pm.status_path in the pool configuration; keep it, but only expose it through an nginx location guarded with the same allow/deny block, and never through a catch-all location ~ \.php$. Cloudflare: a WAF custom rule blocking /server-status, /server-info and /nginx_status for everyone except your monitoring IPs adds a second gate, but attackers who find the origin IP bypass it, so the origin rule is the one that matters. If the page was public, review what was visible in query strings and consider rotating any tokens that appeared.

Where this fits

Exposed server status page is check 6 of 14 that the website vulnerability scanner runs under exposed files and information disclosure, ordered the way they are worth fixing. That ordering is the point: Fixing this one while the check above it still fails buys less than it looks like.

Fix this one first

Above it in the same category sits Directory listing enabled (medium), where the web server generates an index of files for a directory that has no index page, exposing every file in it, including ones that are not linked from anywhere. An attacker who has that does not need this, so it is the better use of the same hour.

What fixing this still leaves open

Exposed server status page closes one route in. Immediately below it: WordPress user enumeration via REST API, where the WordPress REST API or author archives reveal account usernames to anonymous visitors, giving attackers half of each credential pair before they start guessing passwords; WordPress xmlrpc.php enabled, where the WordPress XML-RPC endpoint at /xmlrpc.php is enabled; Exposed .DS_Store file, where a macOS .DS_Store file is served from the web root.

Found in the same scan

The website vulnerability scanner reports this alongside checks from other categories that are at least as serious, including Certificate chain and hostname validation, where the certificate presented for this hostname did not validate: The chain does not reach a trusted root, an intermediate is missing, the name does not match, or the certificate is self-signed or expired, and HTTPS is available, where the site could not be reached over HTTPS on port 443, or the TLS handshake failed. A single run of website vulnerability scanner answers all of them at once.

Prompt for an AI Hand this check to an assistant Sign in to copy it
The first few lines
You are a senior web engineer. I ran a security and SEO scanner against my site and it reported the finding below. Fix it properly rather than suppressing the symptom.

Finding: Exposed server status page (medium severity)
Scanner check id: exposed-server-status
19 more lines, including the evidence and the exact fix

The rest of this prompt names the pages and line numbers we found the problem on, the configuration to change, and the constraints a good answer has to respect. It is free, it just needs an account so the work is not scraped wholesale.

Sign in with Google

Signing in is free and takes one click. We store your email address and nothing else.

References

  1. Apache: Mod_status
  2. nginx: Ngx_http_stub_status_module
  3. PHP-FPM configuration: Pm.status_path

Related guides