Skip to main content
Blog|
Knowledge base

What Happens When Bots Find Your WordPress Login Page

|
Mar 11, 2026|13 min read
KNOWLEDGE BASEWhat Happens When Bots FindYour WordPress Login PageHOSTNEYhostney.comMarch 11, 2026

Every WordPress site has a login page at the same address: /wp-login.php. It is not hidden. It is not secret. And every bot on the internet knows exactly where it is.

Within hours of launching a new WordPress site, automated scripts start hitting that page. Not because your site is a target. Because your site exists. Bots scan IP ranges and domain lists continuously, looking for WordPress installations to probe. Your login page is the first door they try.

Most site owners never see this happening. There is nothing in the WordPress dashboard that tells you 300 failed login attempts happened last night. Your analytics will not show it. Your site just feels a little slower than it should, and you are not sure why.

This post walks through what a credential stuffing attack actually looks like from the server side, what it does to your site’s performance, and how a properly configured hosting environment stops it before it becomes your problem.

What credential stuffing looks like from the server

A credential stuffing attack is not someone guessing your password. It is an automated script working through a list of leaked email and password combinations from data breaches, trying each one against your login page. These lists contain billions of credentials. The attacker does not need to know anything about you. They just need your login page to exist.

Here is what the server sees when an attack starts:

[09:14:01] POST /wp-login.php 302 — 185.x.x.42
[09:14:01] POST /wp-login.php 302 — 185.x.x.42
[09:14:02] POST /wp-login.php 302 — 185.x.x.42
[09:14:02] POST /wp-login.php 302 — 185.x.x.42
[09:14:03] POST /wp-login.php 302 — 185.x.x.42

Five POST requests in two seconds, all from the same IP, all to the same endpoint. Each one submits a different username and password combination. Each one forces WordPress to:

  1. Parse the request and load WordPress core
  2. Query the database to check if the username exists
  3. If it does, hash the submitted password and compare it
  4. Return a response

That is a full PHP execution cycle and at least one database query per attempt. Multiply by hundreds of attempts per minute, and you have a login page consuming more server resources than your actual visitors.

And that is the simple version. Sophisticated attacks rotate through thousands of IP addresses, sending just a few attempts from each one. From any single IP’s perspective, it looks like normal traffic. From the server’s perspective, the login page is getting hammered from every direction.

Why your WordPress site slows down during attacks

WordPress is not built to handle hundreds of login attempts per minute. Each failed login attempt consumes the same server resources as a legitimate page load, sometimes more, because password hashing is deliberately expensive (that is a security feature, not a bug).

Here is what happens to your site during a sustained brute force attack:

PHP workers get consumed. Your server has a limited number of PHP processes available. Each login attempt occupies one until it completes. If bots are using 60% of your PHP workers for login attempts, your real visitors are sharing the remaining 40%. Pages load slowly. Some requests time out entirely.

Database connections spike. Every login attempt queries the users table. Under heavy attack, these queries stack up. Your blog posts, your WooCommerce products, your contact forms, everything that needs the database competes for connections with hundreds of bot requests.

CPU usage climbs for no visible reason. You check your analytics and see 50 visitors. You check your server and see 90% CPU utilization. The gap is bot traffic, and most of it is hitting your login page.

Memory pressure builds. Each PHP process handling a login attempt consumes memory. Under sustained attack, the server can run low on available memory, which triggers slower disk-based operations and degrades performance for everything.

The worst part: none of this shows up in your WordPress dashboard. You do not get an alert saying “your login page received 4,000 requests in the last hour.” You just notice your site is slow, maybe your uptime monitor triggers, and you open a support ticket asking what is wrong.

The xmlrpc.php problem

WordPress has a second entry point that most site owners do not know about: xmlrpc.php. This is the XML-RPC interface, originally designed for remote publishing and pingbacks. It is enabled by default on every WordPress installation.

The reason attackers love xmlrpc.php is that it supports a method called system.multicall , which allows multiple operations in a single request. An attacker can bundle 500 login attempts into one HTTP request. From a rate limiting perspective, that looks like one request. From a resource perspective, it is 500 password checks.

This makes xmlrpc.php a more efficient attack vector than wp-login.php for brute force. One request, hundreds of attempts, and basic rate limiting does not catch it because it only sees one request.

If you are not using xmlrpc.php for remote publishing (most sites are not), there is no reason for it to be accessible. But on most hosting platforms, it sits there, open, processing every request that comes in.

Why security plugins are not enough

The typical advice for WordPress login security is to install a plugin. Wordfence, Sucuri, iThemes Security, they all offer login attempt limiting and IP blocking. They work. But they have a fundamental limitation.

Security plugins run inside WordPress. That means every bot request still has to:

  1. Hit your web server
  2. Start a PHP process
  3. Load WordPress core
  4. Load the plugin
  5. Let the plugin decide whether to block the request

By the time the plugin says “no,” the server has already done most of the work. The CPU cycles are spent. The PHP worker was occupied. The database connection was opened. The plugin prevented the login, but it did not prevent the resource consumption.

This is not a criticism of security plugins. They are valuable tools and they add real protection. But they operate at the application layer, which means the server has already processed the request before the plugin gets a chance to reject it.

To actually protect your server resources, bot traffic needs to be stopped before it reaches WordPress. That means handling it at the web server level, before PHP even starts.

How server-level protection actually works

The difference between application-level and server-level protection is where the decision happens.

When a bot hits wp-login.php on a server with only plugin-level protection:

Request → Web server → PHP → WordPress → Plugin → "Blocked"

Every step in that chain consumes resources. The bot is blocked, but your server did the work.

When a bot hits wp-login.php on a server with proper server-level protection:

Request → Web server → "Blocked"

The request never reaches PHP. WordPress never loads. No database query runs. The server spends microseconds instead of milliseconds on the request, and your PHP workers remain available for your real visitors.

This is not theoretical. On our servers, we see login-targeted bot traffic stopped at three distinct layers before it ever touches WordPress:

Layer 1: Request rate limiting on login endpoints

The web server enforces a strict rate limit specifically on wp-login.php and xmlrpc.php. Legitimate users logging into WordPress do not need to submit credentials more than a few times per minute. A bot submitting dozens of attempts per second immediately exceeds this limit and gets rejected with a 429 (Too Many Requests) response.

This is the simplest layer and it catches the most aggressive attacks, the ones that send as many requests as possible as fast as possible. The server returns a tiny error response without starting PHP, without loading WordPress, without touching the database.

Layer 2: Behavioral pattern detection

Rate limiting catches the fast attacks, but smarter bots slow down. They send one attempt every few seconds, staying just under the rate limit. From a pure request-rate perspective, they look like a human typing slowly.

But they do not look like a human in other ways. A real person logging into WordPress visits the login page once, enters their credentials, and either succeeds or tries again. They have a browser that accepts cookies. Their request includes standard headers that browsers send automatically. They came from somewhere, a bookmark, a link, the admin bar.

A bot submitting credentials every four seconds for an hour has a completely different behavioral fingerprint. It hits the same endpoint repeatedly with no variation. It often does not accept cookies. Its request headers are minimal or inconsistent. It never requests any other page on the site.

Our servers evaluate these behavioral signals in real time, inline with each request. When enough signals indicate automated behavior, the server serves a proof-of-work challenge: a small computational puzzle that a real browser solves automatically in about two seconds. The visitor sees a brief loading screen, the puzzle completes, and they continue to the login page.

A bot that cannot execute JavaScript, which is most of them, sees HTML it cannot process. It either gives up or keeps requesting the same page, which only strengthens the behavioral signal.

Layer 3: Reputation scoring across the platform

The first two layers handle the immediate threat. The third layer builds a longer-term picture.

Every IP that interacts with websites on our platform accumulates a reputation score based on its behavior across all the sites it touches. An IP that is attempting logins on your site might also be scanning for configuration files on another site and scraping content from a third. Each of these behaviors contributes to the overall score. We explain the full scoring system and all twelve signals in How to Stop Bot Traffic at the Origin.

An IP that is exclusively hitting login pages across multiple unrelated websites, never visiting any actual content, gets identified as a single-purpose brute forcer. That pattern is not something a human produces. The score climbs, and once it crosses the threshold, the IP is challenged or blocked across every server in the fleet.

This matters because coordinated attacks distribute their attempts across many targets. An attacker sending five attempts to each of 1,000 different WordPress sites does not look suspicious from any single site’s perspective. But from the platform’s perspective, it is obvious: one IP, 5,000 login attempts, zero page views. That gets caught.

What this looks like in practice

Let’s walk through a real attack scenario as the server sees it:

Minute 0: A new IP starts sending POST requests to wp-login.php at about 2 per second. The rate limit on the login endpoint kicks in immediately. After the first few requests, every subsequent attempt gets a 429 response. PHP never starts. WordPress never loads.

Minute 1: The bot does not care about 429s. It keeps sending requests, now at a higher rate. The real-time rate detection layer notices the volume spike and escalates: instead of a 429, the IP now receives a proof-of-work challenge page. The bot cannot execute JavaScript, so it keeps hitting the challenge page in a loop.

Minute 2: The bot has now accumulated multiple signals: high request rate, repeated login endpoint targeting, failed to solve the proof-of-work challenge, no cookies accepted. The edge layer escalates further. The IP gets a hard block. Every request returns an immediate 403 with no processing.

Minute 10: The platform-wide scoring engine runs its cycle. It sees this IP’s accumulated signals: rate limit violations, login-only targeting, unsolved challenges, no legitimate page views. The score is high. The IP is flagged across every server. Even if the attacker switches to targeting a different site on a different server, the ban is already in place.

Throughout all of this, your site was unaffected. Your real visitors loaded pages normally. Your PHP workers handled legitimate requests. Your database served actual content. The attack consumed server resources measured in microseconds per request, not milliseconds.

The attacks you do not see

The scenario above describes an obvious attack, one IP blasting requests as fast as possible. Those are easy to detect and stop. The harder problem is the attacks that are designed to look normal.

Distributed credential stuffing uses thousands of residential IP addresses, each sending only a few attempts. No single IP triggers rate limiting. No single IP looks suspicious. But collectively, your login page receives 10,000 attempts in an hour from 5,000 different IPs.

This is where platform-level visibility matters. A single site cannot see the pattern. But a hosting platform that monitors traffic across thousands of sites can see the same credential list being worked through across multiple targets simultaneously. The IPs involved start accumulating reputation signals from multiple sources, and the scoring engine connects the dots.

Slow credential stuffing sends one attempt every 30 seconds from a single IP. It stays below every rate limit. But it runs 24/7. Over a week, that is over 20,000 attempts from one address. The behavioral pattern detection catches this: an IP whose only activity on any site, ever, is submitting login forms is not a human. It does not matter how slowly it does it.

These are the attacks that security plugins struggle with the most, because each individual request looks legitimate. The defense has to come from seeing the bigger picture.

What you can do right now

Even on a hosting platform with server-level bot protection, there are steps you should take to reduce your attack surface:

Use strong, unique passwords. This is the most effective defense against credential stuffing. If your password was not in a data breach, it is not on any credential list. Use a password manager. Do not reuse passwords across services.

Enable two-factor authentication. Even if an attacker guesses the right password, 2FA stops them. Plugins like WP 2FA or Google Authenticator add this to WordPress in minutes.

Use a unique username. Do not use “admin” as your WordPress username. Bots try “admin” first because it works on a surprising number of sites.

Disable XML-RPC if you do not use it. If you do not publish remotely using desktop or mobile apps, you do not need xmlrpc.php accessible. Many hosting platforms, including ours, let you disable it with a single toggle.

Keep WordPress and plugins updated. Bots do not only target login pages. They scan for known vulnerabilities in outdated plugins. An up-to-date site has a smaller attack surface.

Check your access logs periodically. Even if you have server-level protection, it is worth understanding what your site faces. Look at the requests to wp-login.php and xmlrpc.php. If you see hundreds of attempts from IPs you do not recognize, your hosting is handling it. If those requests are reaching WordPress and consuming resources, that is a conversation to have with your hosting provider.

The hosting provider's responsibility

Here is what we believe: bot traffic on your login page is not your problem to solve. It is ours.

You chose to run a WordPress site. You should be focused on your content, your products, your customers. You should not have to become a security engineer to keep your login page from consuming all your server resources.

That is why we built bot detection into the infrastructure itself. It runs on every server, for every site, automatically. You do not install anything. You do not configure anything. The system handles login-targeted bot traffic the same way it handles every other type of automated abuse, by stopping it at the server before it reaches your application.

If you want visibility into what the system is catching, the Firewall section in your control panel shows exactly which IPs have been challenged or blocked, what signals triggered the action, and how much bot traffic your site is receiving. If you believe a legitimate IP was incorrectly flagged, you can whitelist it with one click.

But you should never have to think about it unless you want to. That is the point.

Wrapping up

Your WordPress login page is under attack right now. Not because you did something wrong. Because every WordPress login page is under attack, all the time. The question is not whether bots are hitting your site. The question is whether your hosting stops them before they waste your server resources.

Security plugins add valuable protection at the application layer. But by the time a plugin blocks a request, your server has already spent the resources to process it. Real protection means stopping bot traffic before PHP starts, before WordPress loads, before the database is queried.

If you are seeing unexplained slowdowns, high CPU usage with low visitor counts, or login attempts in your security logs, automated traffic is the likely cause. On our platform, that traffic is handled at the server level, automatically, across every site we host.

If you want to see what your site is actually facing, the data is in your control panel. And if you have questions about what you are seeing, our support team can walk through it with you.