Back to scan results
Check 20 of 24

Admin Panel Discovery

Application-level admin login pages — distinct from the server control panels in Check 11 — left open to the public internet are continuously hammered by credential-stuffing botnets. We probe the well-known URLs and report any that respond with a login form.

What this check probes

HEAD/GET on the standard admin paths:

  • WordPress — /wp-login.php, /wp-admin/, /xmlrpc.php.
  • Joomla — /administrator/.
  • Drupal — /user/login, /?q=user/login.
  • Magento — /admin/, /index.php/admin/.
  • Generic — /admin, /admin.php, /administrator, /login, /signin, /portal, /dashboard, /cms, /backend.
  • App-server — /manager/html (Tomcat), /host-manager/html, /jenkins/login.

For each response we look at the status (200), content type (HTML), and the body for form fields with names like user, username, password — distinguishing a real login form from a 404 page that happens to return 200.

Why this matters for PCI DSS

An exposed login page is the funnel for several attack types:

  • Credential stuffing — botnets try usernames + passwords from previous breaches. WordPress sites see thousands of attempts a day from automated tools.
  • Brute force — short passwords are tried exhaustively. Even 10 attempts/sec against a 6-character password completes in days.
  • Username enumeration — many platforms reveal whether the username exists via different error messages or response timing.
  • CVE exploitation — if the panel itself is unpatched (e.g., a critical WordPress core CVE), the attacker doesn't need credentials.

PCI DSS 4.0 Requirement 8.3.1 requires strong authentication. Requirement 8.3.6 requires lockout after 10 invalid attempts. Requirement 8.4.2 requires multi-factor authentication for all administrative access. Requirement 7.2 requires need-to-know access.

How to fix it

In rough order of effectiveness:

  1. Restrict by IP at the web server. Only your office, admin homes, or VPN range can reach the URL.
  2. Enforce MFA for every admin account. Mandatory, not optional. TOTP via Google Authenticator / Authy is free and effective.
  3. Rate limit at the proxy or with a plugin (Wordfence, Limit Login Attempts Reloaded, fail2ban). Lockout after 5–10 failed attempts for 15 minutes minimum.
  4. CAPTCHA on the login form to break automated stuffers.
  5. Rename the URL — security through obscurity, but reduces drive-by hits dramatically. WordPress: WPS Hide Login plugin.

nginx IP allow-list (WordPress example):

location ~ ^/(wp-login\.php|wp-admin/) {
    allow 203.0.113.10;
    allow 198.51.100.42;
    deny all;
    # then the normal PHP handler:
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php-fpm.sock;
}
location = /xmlrpc.php { deny all; }

Apache (.htaccess in /wp-admin/):

<Files wp-login.php>
    Require ip 203.0.113.10 198.51.100.42
</Files>

Cloudflare — Zone → Security → WAF → Custom rule: "URI Path contains /wp-login.php AND IP Source Address is not in {office, home}" → Block.

Disable XML-RPC on WordPress unless you actively need it (Jetpack, mobile app, IFTTT). It's an alternative login endpoint that bypasses many login-page protections.

Audit accounts — every admin account should be (a) for a current employee or contractor and (b) using a unique strong password (use a password manager). Disable defaults.

Fixed it? Re-run the scan to confirm.

Run scan again