How to Check If Your Website Admin Panel Is Exposed to the Internet
Admin panels left publicly accessible are a top attack target. Here's how to detect exposed admin paths before attackers do.
If /admin, /wp-admin, or /administrator responds with a login page on your production domain, it's reachable by anyone with a browser and a wordlist. That's not a theoretical risk — credential stuffing bots continuously scan for these paths. A 2023 Cloudflare report found that roughly 20% of all HTTP requests to web applications are automated probes, with admin paths among the most targeted.
Why exposed admin panels matter
The admin panel is the highest-privilege interface on your application. If an attacker can reach the login form, they can:
- Run credential stuffing attacks using leaked password dumps (Collection #1 alone contained 2.7 billion credential pairs)
- Exploit unpatched vulnerabilities — WordPress admin panels have seen dozens of auth-bypass CVEs (e.g., CVE-2023-2745, a directory traversal that exposed admin-readable files)
- Abuse "forgot password" flows to enumerate valid usernames
- Use the panel as a pivot if it accepts IP ranges broader than intended
Restricting who can reach the login page is defense-in-depth. A strong password alone is not sufficient when automated attackers can make thousands of attempts per minute.
Common admin panel paths
Attackers use tools like dirsearch and gobuster with wordlists containing tens of thousands of paths. The most frequently probed include:
/admin,/admin/,/admin/login/wp-admin/,/wp-login.php(WordPress)/administrator/,/administrator/index.php(Joomla)/user/login,/user/register(Drupal)/panel,/cpanel,/dashboard/manage,/management,/backend/phpmyadmin,/pma,/mysql/jenkins,/jenkins/login/grafana,/kibana,/portainer
How to check if yours is exposed
The fastest check is a direct HTTP request. For each path you want to verify:
curl -s -o /dev/null -w "%{http_code} %{url_effective}" https://yourdomain.com/admin/
curl -s -o /dev/null -w "%{http_code} %{url_effective}" https://yourdomain.com/wp-admin/
curl -s -o /dev/null -w "%{http_code} %{url_effective}" https://yourdomain.com/phpmyadminA 200 or 302 (redirect to login) confirms public reachability. A 403 means the path exists but is IP-restricted — better, but the path itself is discoverable. A 404 is ideal.
For a broader scan against your own domain, gobuster with the SecLists admin wordlist:
gobuster dir -u https://yourdomain.com \
-w /usr/share/seclists/Discovery/Web-Content/AdminPanels.fuzz.txt \
-b 404 -t 50 --timeout 10sThis surfaces any path that returns something other than 404 — including 200, 301, 302, 401, and 403 responses.
Reading the response carefully
HTTP status alone isn't enough. A misconfigured application might serve a login page with a 200 from /wp-login.php while returning 404 for /wp-admin/. Always inspect the response body:
curl -s https://yourdomain.com/wp-login.php | grep -i 'wp-login\|wordpress\|log in'Look for form action targets, CMS identifiers, or framework-specific strings. A response that includes action="https://yourdomain.com/wp-login.php" is a WordPress login form regardless of the status code the load balancer returned.
Remediation
IP allowlisting at the web server level
The most reliable fix is restricting access by IP before the application processes the request. In Nginx:
location /wp-admin/ {
allow 203.0.113.10; # office IP
allow 198.51.100.0/24; # VPN range
deny all;
}
location = /wp-login.php {
allow 203.0.113.10;
allow 198.51.100.0/24;
deny all;
}In Apache with .htaccess:
Require ip 203.0.113.10
Require ip 198.51.100.0/24
Move the admin to a non-standard path
Plugins like WPS Hide Login (WordPress) or framework middleware can change /wp-admin to an unpredictable string like /xy29qm. Security through obscurity is not a primary control, but it eliminates automated wordlist hits and substantially reduces your attack surface in practice.
Put it behind a VPN or zero-trust gateway
For teams with a VPN or a tool like Cloudflare Access, require authentication at the network layer before the login page is served. This is the approach that survives CMS vulnerabilities — even if a bug exists in the admin panel software, exploiting it requires network access first.
Rate-limit and add MFA
If public access is necessary (e.g., multi-location teams without a VPN), implement IP-based rate limiting and require TOTP or WebAuthn. WordPress: plugins like Limit Login Attempts Reloaded and WP 2FA. Custom apps: implement lockout after N failed attempts and enforce MFA for all admin accounts.
Common mistakes
- Blocking
/wp-admin/but not/wp-login.php— these are separate entry points; block both - Relying on
robots.txtdisallow rules —Disallow: /admintells attackers exactly where to look - IP allowlisting only at the application level — if the app itself has a vulnerability before authentication, the IP check never runs
- Forgetting the API endpoint — WordPress
/wp-json/wp/v2/usersexposes usernames even when wp-admin is locked; add JSON API restrictions separately - Staging environments —
staging.yourdomain.com/wp-adminis commonly left open and often shares production credentials
Ongoing monitoring
Admin panel exposure can be reintroduced by deployments, CMS updates, or infrastructure changes. A one-time check is not enough. Orb44's outside scan checks for exposed admin endpoints on every scan and alerts you when a path that was previously returning 404 starts returning 200 or 302. It covers WordPress, Joomla, Drupal, and generic admin paths from a regularly updated signature list.
FAQ: Is a 403 response safe?
A 403 (Forbidden) means the server acknowledged the path exists and actively denied access. It's better than 200, but the path is now confirmed as real to anyone probing it. Prefer returning 404 — either by blocking at the reverse proxy with a 404 response or by moving the admin to a non-standard path. Some security teams argue the distinction is minor; others treat confirmed-path-plus-403 as a finding worth resolving.
FAQ: Does changing the admin path break anything?
For WordPress, the WPS Hide Login plugin handles the redirect transparently — existing bookmarks stop working (expected), but the plugin provides a configurable new URL. For custom applications, you control the routing; renaming the route is a one-line change in most frameworks. Remember to update any internal tooling, monitoring agents, or health checks that reference the old path.
FAQ: Should I block the XML-RPC endpoint too?
Yes. /xmlrpc.php accepts authentication and has been used to brute-force credentials via the system.multicall method, which allows batching thousands of login attempts in a single request. Unless you're using a plugin that requires XML-RPC (some backup and publishing tools do), disable it entirely. Add Deny from all in .htaccess or the equivalent Nginx deny all block.