• Resolved James

    (@en7jos)


    Hi,

    I’ve been having issues with brute force login attacks against my WP install for the past few months which have managed to bring the server down a couple of times. This is despite having BPS Security and Wordfence installed. Actually I’m not sure whether Wordfence could be part of the problem as it obviously take resources to check and block IPs in this way. Going by the ‘block’ records there can be many attempts from lots of different IPs within a short space of time.

    So I was obviously interested by the ‘extra brute force protection’ code that popped up from BPS Security in my admin area and I added the following code to the htaccess wizard as you suggested:

    # Protect wp-login.php from Brute Force Login Attacks based on Server Protocol
    # All legitimate humans and bots should be using Server Protocol HTTP/1.1
    RewriteCond %{REQUEST_URI} ^/wp-login\.php$
    RewriteCond %{THE_REQUEST} HTTP/1\.0
    RewriteRule ^(.*)$ – [F,L]

    I want customers to be able to login still so the IP based login restriction wasn’t right for me, but the above seemed to work. But still getting lots of brute force attacks I wondered whether there was anything else that could be done by the htaccess files to stop things getting as far as WordFence blocking.

    After a search, I found a few interesting articles and put together the following code which I have also added to my htaccess wizard:

    # Protect wp-login and wp-comments-post by checking referrer is own website
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} POST
    RewriteCond %{REQUEST_URI} .(wp-comments-post|wp-login)\.php*
    RewriteCond %{HTTP_REFERER} !.*example.com.* [OR]
    RewriteCond %{HTTP_USER_AGENT} ^$
    RewriteRule ^(.*)$ – [F,L]
    </ifModule>

    As I understand it, this looks for the referrer when someone requests the login or comments pages and if it isn’t the website address (example.com above) then it blocks them. Nice that it works for both brute force login attempts against the WP login page and also against automated spam bots.

    So I just wanted to paste the code here to get your opinion of whether it is likely to be useful, and whether it could be improved in any way? Could it be combined with the top code that you have already suggested perhaps?

    It seems to be working for me – Wordfence has only blocked a couple of login attempts (with non-existent usernames) in the past couple of days, as opposed to countless before that (but this might just be a lull in the attacks?) Also the obviously automatically generated login attempts (usernames of admin and my domain name) seem to have stopped, the ones getting through to Wordfence seem to have more human generated usernames.

    Thoughts, comments or suggestions gratefully received!

    James 🙂

    http://wordpress.org/plugins/bulletproof-security/

Viewing 8 replies - 1 through 8 (of 8 total)
  • Plugin Author AITpro

    (@aitpro)

    Yes, this code is useful. The ongoing Brute Force Login attacks are very tricky to handle in general for Hosts and I’m sure this is driving them a little wiggy.

    By adding your additional code above you are decreasing the overall load on your Host’s Server since instead of the Server having to process a bunch of bot requests these bot requests are stopped before the Server has to process them so if everyone was doing this it would add up to significant benefit for Hosts.

    To be code correct make these slight adjustments to the REQUEST_URI condition

    RewriteCond %{REQUEST_URI} \.(wp-comments-post|wp-login)\.php

    You do not need the last dot, but if you wanted to keep it then this is code correct:

    RewriteCond %{REQUEST_URI} \.(wp-comments-post|wp-login)\.php.*

    Plugin Author AITpro

    (@aitpro)

    oops I totally got that wrong. LOL that’s what happens when you are doing 10 things at once.

    You do not need the starting or ending dots. If you added them then the code is negated since the starting dot escaped is not matching the correct conditions. Sorry.

    RewriteCond %{REQUEST_URI} (wp-comments-post|wp-login)\.php

    Thread Starter James

    (@en7jos)

    Hi. Thanks for that. Had another web search to try and re-find where I got the additional code above from, and found that it was on the WordPress codex pages here:
    http://codex.wordpress.org/Brute_Force_Attacks#Deny_Access_to_No_Referrer_Requests

    ———————————————
    # Stop spam attack logins and comments
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} POST
    RewriteCond %{REQUEST_URI} .(wp-comments-post|wp-login)\.php*
    RewriteCond %{HTTP_REFERER} !.*example.com.* [OR]
    RewriteCond %{HTTP_USER_AGENT} ^$
    RewriteRule (.*) http://%{REMOTE_ADDR}/$ [R=301,L]
    </ifModule>
    ———————————————

    So just wanted to double check that your suggested mod’s were correct being as though the code came from the WP gurus!

    Cheers, James

    Plugin Author AITpro

    (@aitpro)

    The starting dot means match any character, except for line breaks if dotall is false, but the technically correct way to to do this with Regular Expression code is you are supposed to use .* I personally like to put this RegEx in a group (.*) in some cases, which is just a personal preference for visual reasons.

    In this case the URI will match wp-comment-post.php and wp-login.php with or without the dot. Visually it bugs me, but it is not wrong so to speak.

    Here is a great site (AKA RegEx Playground) to test and create Regular Expression code: http://gskinner.com/RegExr/

    Thread Starter James

    (@en7jos)

    Thanks. So is the * at the end of this line not needed also?

    Would it be more efficient (less server load) to combine this with your original code? i.e. a single code block that blocks access to these files when the Server Protocol is HTTP/1.1 OR there is no referrer? If so, what would the correct syntax be?

    Finally I was wondering whether this should also be extended to cover all the files in the wp-admin directory. What do you think? Again I’m not really sure of the correct syntax.

    I realise that these questions are not really support for your plugin, so you help and suggestions are much appreciated from someone who sort of knows what they want to achieve, but doesn’t have the required coding knowledge! Hopefully this thread might be useful to other BPS users too…. 🙂

    Plugin Author AITpro

    (@aitpro)

    The * asterisk means Match 0 or more of the preceeding token. This is a greedy match, and will match as many characters as possible before satisfying the next token. So technically this is incorrect or just not doing anything unless you added a dot .* but you don’t need this anyway.

    Let’s say for example there is a Query string after this: /wp-login.php?foo=bar. This condition below will still match the URI condition with or without using .*

    RewriteCond %{REQUEST_URI} (wp-comments-post|wp-login)\.php

    There would be no significant difference/performance hit either way – either combined or in separate blocks of code.

    I guess you could try this for files in the wp-admin folder, but BPS is already protecting wp-admin files. Totally up to you – experiment away! 🙂

    No problem and always glad to help in any way I can – duck => water <> Ed => troubleshootin’ LOL 😉

    Thread Starter James

    (@en7jos)

    Cheers 🙂

    Plugin Author AITpro

    (@aitpro)

    Resolving.

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘Protecting against brute force attacks’ is closed to new replies.