Protecting .htaccess from Better WP Security (revisited)

A few months ago I wrote about experiencing corruption issues with the .htacccess file.  I discovered the problem was with a WordPress security plugin called Better WP Security.  It’s an excellent plugin except for that one issue.

A common attack on WordPress sites (at least it is with mine) has been with botnets attempting to guess the username and password combinations to get access to the administrative section.  My guess is that they want access in order to host their malware somewhere on the server and spam email with links to it.  The username the botnet tries is almost always admin or administrator.  Let that be a lesson to never use those for your login name.  Create a different login and delete admin or administrator.  It’s one thing Better WP Security checks for.  See a file I created for a lengthy example of attempts to hack into my site.  I deleted the more R-rated password attempts.

The corruption happens when Better WP Security attempts to ban more than one IP address at the same time (or nearly the same time).  It does this by modifying .htaccess.  The file gets corrupted when one thread or process has it open and is changing it but another thread (or process) opens the file in the middle of that and attempts to change it as well.

I’m writing this entry because someone recently wrote to me asking for clarification on how to make the changes to protect .htaccess from corruption.  In my method, you have to place a “dummy” file on your server.  It can be any file, even a 0 byte file.  It just has to exist.  I used cPanel’s file manager to place the file into my root public_html directory.  For this example, let’s call the file dummyFile.txt (You can name it whatever you want to).

Next you need to edit better-wp-security/inc/admin/common.php.  I did it by logging into the administrative section of WordPress and under Plugins (on the left), I clicked Editor.  From there, just select Better WP Security and press Select.  If you don’t see common.php, which I never do when I first get to that screen, try clicking better-wp-security/inc/auth.php.  After clicking that, common.php always shows up for me.

Once in common.php, find

function writehtaccess() {

Right after that, add the following:

        // BEGIN ADD
            $ourFileName = "/dummyFile.txt";
            $ourFileHandle = fopen($_SERVER['DOCUMENT_ROOT'] . $ourFileName, 'a') or die("can't open file");

            if (flock($ourFileHandle, LOCK_EX) == false)
                $sleepTime = rand(100000, 500000);

                while (flock($ourFileHandle, LOCK_EX) == false)
                    usleep ($sleepTime);

        // END ADD

Again, the code assumes you added a file called dummyFile.txt to the root of the HTML section of your server.  You can change that to whatever and wherever you added your file.

The code attempts to open and lock dummyFile.txt.  If it’s successful, it skips the if statement’s block and continues with the rest of the code.  If it is unable to lock the file (because another thread or process has already locked it), it generates a wait time between .1 and .5 seconds and continuously checks to see if it can get the lock at each time interval.

It’s important to unlock the file before exiting the code.  I added code to do that just before the

return 1; //success

statement that exits the writeheaccess() function which is just before the comments for

function writewpconfig() {

The code to add is:

        // BEGIN ADD

            flock($ourFileHandle, LOCK_UN);

        // END ADD

That code unlocks the file and closes it.  It’s actually better to add it before all the return statements in the writehtaccess() function but I’ll admit that I didn’t do that.  All the other return statements deal with errors that the code might encounter and I just assume it’ll work properly.  It has for months!

That’s it.  If you add those two sections of code, I found the .htaccess file will no longer experience the corruption issue from Better WP Security.  You will have to add the code back in each time you update the plugin.  So don’t forget to do that!