Search for “xmlrpc.php attack” and most of what you’ll find repeats the same story from 2015: a single request to xmlrpc.php can test hundreds of passwords at once, using a method called system.multicall. That story used to be completely true. It hasn’t been true for anyone running a remotely current WordPress install since version 4.4, released in December 2015.
That’s not a reason to stop worrying about xmlrpc.php. It’s a reason to be precise about what’s actually still exploitable, because the outdated version of this story leads people to either panic about something already fixed, or worse, assume the whole file is harmless now that the famous bug is gone. Neither is accurate.
What Actually Happened in 2015
The original discovery, published by Sucuri, was genuinely serious. WordPress’s XML-RPC interface supports a method called system.multicall, designed to let you bundle several remote procedure calls into a single request. Attackers realized they could bundle hundreds of username-and-password login attempts into that one request, turning what should have taken hundreds of separate, rate-limitable attempts into a single request that most security tools weren’t watching closely.
WordPress core fixed this directly. You can read the actual patch yourself: core.trac.wordpress.org ticket #34336, closed and shipped in WordPress 4.4. The fix is specific and verifiable: inside a single system.multicall request, the moment one login attempt fails, every subsequent attempt in that same call automatically fails too, without even being processed. The bundling trick that made the attack fast is gone. It’s been gone for over a decade.
What’s Still Genuinely True Today
Two things survived that patch, and neither gets mentioned nearly as often as the outdated multicall story.
xmlrpc.php is still a separate login door. The multicall amplification is dead, but xmlrpc.php can still accept one login attempt per request, the same as wp-login.php can. Most brute-force protection, on a lot of sites, is built specifically around wp-login.php: rate limiting the login form, locking out an IP after repeated failures there. If that protection doesn’t also watch xmlrpc.php, an attacker gets a second, quieter front door that nobody’s monitoring, one guess per request, just automated across enough requests to make volume work in their favor again.
Pingback abuse was never patched, because it isn’t a bug. The pingback.ping method exists to let WordPress sites notify each other about links, and it works exactly as designed. That design can be weaponized: an attacker sends a forged pingback request naming a victim’s URL as the “source,” and your WordPress install dutifully sends a request to that victim to verify the link. Do this across enough vulnerable sites at once and you’ve built a distributed denial-of-service attack using other people’s servers as the delivery mechanism, plus a way to probe internal or otherwise-unreachable URLs from your server’s network position. There’s no core patch for this because there’s nothing technically broken, it’s legitimate functionality doing exactly what it’s supposed to do, aimed somewhere it shouldn’t be.
The Wrong Fix, and the Right One
The blunt advice you’ll see everywhere is “just disable XML-RPC entirely.” For a lot of sites that’s genuinely fine. For sites running Jetpack, or using the WordPress mobile app, or relying on certain remote publishing tools, it isn’t, those depend on XML-RPC working, and disabling it wholesale breaks real functionality to fix a problem that doesn’t require breaking everything.
The more precise fix removes only the specific methods that get abused, pingback.ping, pingback.extensions.getPingbacks, and system.multicall, while leaving the rest of XML-RPC intact for anything that legitimately needs it. Rate limiting requests to xmlrpc.php specifically, separate from your login-page rate limiting, closes the “quiet second door” problem without needing to know in advance whether you’re using Jetpack.
That’s the actual, current shape of this problem: one famous piece of it fixed a decade ago, two real pieces still live today, and a fix that doesn’t require choosing between security and functionality.
See how SecondGate handles this
Sources: WordPress core trac ticket #34336 (the actual fix), Sucuri’s original 2015 writeup (the original discovery).






