-
-
Save jaydansand/dcb66a0e36365c178a91 to your computer and use it in GitHub Desktop.
| <?php | |
| /* | |
| Plugin Name: XMLRPC Slowdown | |
| Plugin URI: | |
| Description: Deliberately introduce some delay into XMLRPC calls to rate limit brute-force and DoS attacks. | |
| Version: 1.0 | |
| Author: Jay Dansand | |
| Author URI: | |
| */ | |
| /** | |
| * Implement filters xmlrpc_enabled and xmlrpc_login_error. | |
| * | |
| * @see class-wp-xmlrpc-server.php | |
| */ | |
| function xmlrpc_slowdown_filter_sleep($arg) { | |
| // Keep track of calls (should be 1 or 2) to increase delay | |
| // when called after a login failure. | |
| static $calls = 0; | |
| ++$calls; | |
| $rand = function_exists('mt_rand') ? 'mt_rand' : 'rand'; | |
| usleep(call_user_func($rand, 500000 * $calls, 2000000 * $calls)); | |
| return $arg; | |
| } | |
| add_filter('xmlrpc_enabled', 'xmlrpc_slowdown_filter_sleep'); | |
| add_filter('xmlrpc_login_error', 'xmlrpc_slowdown_filter_sleep'); |
Thanks for the comment/concern! I get the theory, but I must be missing something: if each attacking node (for example, let's say 50 of them) limits itself to any finite number of simultaneous connections (let's say 5), then regardless of whether you're responding really quickly or really slowly, they're still going to be occupying on average 50 * 5 = 250 workers (or any other finite number) at a time, right? The only situation where this script would cause a logjam (where there wasn't nearly one already) is where the brute force attacker is simply spawning new requests as quickly as it can, not waiting for previous requests to finish. That's no longer someone trying to log in, that's someone trying to take you down. Admittedly, this script does not help with that at all!
FYI, I've seen this kind of mitigation in use before and if someone is bruteforcing xmlrpc, the results aren't pretty - you'll end up with all your workers occupied because each call is taking a lot longer. I'd simply no-op an increasing percentage of requests so the workers can finish a request and move onto the next etc.