Stop WordPress login attempts before they reach php -

WordPress hosting done right. done fast. done secure


Stop WordPress login attempts before they reach php

stop WordPress bot login attempts

Everyone that’s run a WordPress site, or runs a VPS, knows the pain of DDoS repeated login attempts stealing all your CPU.  What if you could block the hits before they hit WordPress and php ?

Below is some information you can use on either:

  • a border layer 7 tool, like a load balancer
  • a border layer 7 firewall
  • you could even add these to .htaccess, as apache runs before php
  • we use haproxy – and I’ll show you the code we use

If you can block the login attempts before they hit WordPress and php – not only is it safer, but it saves all your CPU for real WordPress pages and work.

Not only might they eventually guess a password, but all the attempts consume oodles of resources. In shared hosting it often takes your site offline – because the hosting company says your using too many resources. In a VPS it just consumes so much CPU that all sites start to go slow.

The standard approach is something like fail2ban or WordFence. In both cases they wait for a certain number of hits, and then block the IP address. This approach obviously uses some resources to allow the first hits.

More recently I had to stop an attack that only did 6 hits from each IP address. The attacker just had a lot of IP addresses in their BOT army. So the fail2ban approach just doesn’t work. The same attack also just attempted a http GET on /wp-admin/ – without even a login attempt, which consumed more resources.

My idea is to filter the requests to /wp-admin/ and /wp-login.php based on low level testing (layer 7) of the entire http request. If the request looks like a BOT, then send a redirect. If my code guesses wrong and it is a real human – then the redirect just get’s them to login again.

The Details

I look for a few markers in the requests:

  • the wordpress_test_cookie cookie. This get’s set by WordPress just to test if you have cookies enabled.
  • a http referrer header
  • a http Accept header
  • a http Accept-Encoding header
  • a http Accept-Language header

The entries above are all optional for http, and you could in fact login without them.

But a real browser request from a real human has all of those fields completed all of the time.

Bot programmers are lazy – and just send the minimum headers.

So if a login attempt is requested without any of those, I just redirect to /wp-admin/. If it’s a real human they’ll have to login again.

Here is our haproxy recipe

acl browsertest1 path_beg /wp-login.php
acl browsertest2 hdr(Referer) -m found
acl browsertest3 hdr(Accept) -m found
acl browsertest4 hdr_sub(cookie) wordpress_test_cookie
acl browsertest5 hdr(Accept-Encoding) -m found
acl browsertest6 hdr(Accept-Language) -m found

http-request redirect code 303 location /wp-admin/ if browsertest1 !browsertest2 METH_POST
http-request redirect code 303 location /wp-admin/ if browsertest1 !browsertest3 METH_POST
http-request redirect code 303 location /wp-admin/ if browsertest1 !browsertest4 METH_POST
http-request redirect code 303 location /wp-admin/ if browsertest1 !browsertest5 METH_POST
http-request redirect code 303 location /wp-admin/ if browsertest1 !browsertest6 METH_POST


BOT jail

We’ve also implemented a BOT jail for WordPress logins.

If you attempt any WordPress login, and you don’t have the wordpress_test_cookie cookie – then we redirect to a page that uses a HTML redirect. BOTs in general don’t read the page, and thus just get stuck. When a real user accesses the page the browser just redirects and they login as normal.

Once they login, they get the wordpress_test_cookie cookie that seems to persist forever – so on future login attempts they don’t get the jail page.

WordPress bot jail

Here’s our haproxy code for the bot jail

acl browsertest1b url_end -i /wp-admin/
acl browsertest1c url_end -i /wp-login.php
acl browsertest4 hdr_sub(cookie) wordpress_test_cookie
use_backend wpadmin_url if browsertest1b !browsertest4
use_backend wpadmin_url if browsertest1c !browsertest4

backend wpadmin_url
  mode http
  errorfile 503 /etc/haproxy/wpadmin.redirect.html

contents of wpadmin.redirect.html :

HTTP/1.0 200 Found
Cache-Control: no-cache
Connection: close
Content-Type: text/html
< html >  
< body > 
< http-equiv="refresh" content="1; url=/wp-admin/?browsertest">

wpDone bot check security
This is a simple test to make sure you aren't a bot. You see bot's can't read.
This page will auto redirect before you read this.

but if it doesn't , click the link below.
Humans click here to continue  (put an 'a href' to /wp-login.php?humantest )

< /html >  
< /body > 

Here’s a similar idea for apache

# block comment spam by denying access to no-referrer requests
RewriteEngine On
RewriteCond %{REQUEST_URI} wp-login\.php
RewriteCond %{HTTP_REFERER} !(.*)ADDYOURDOMAINHERE\.com(.*) [OR]
RewriteCond %{HTTP_USER_AGENT} ^-?$
RewriteRule .* [R=301,L]

By on May 4th, 2018 ,

Email or call, and we can arrange a time to chat call 0412927156 or CONTACT US TODAY!