All in One WP Security & Firewall is a security plugin for WordPress. You can download this plugin for free from the WordPress repository; or you can install it from the convenient plugin installation tab on your website’s WordPress administration back-end.
My test environment is running WordPress in debug mode, with PHP errors set to display all. For this review I tested “All in One WP Security & Firewall” version 3.1 on a clean install of the newly released WordPress 3.8, with the funky new admin area color scheme. (I had to change the color scheme in my user settings; white text on a black background makes my eyes swim.)
This test did require me to clean my test environment before testing this plugin, because the last plugin I tested did not clean up after itself upon uninstallation. Let’s see how this plugin compares.
First impressions
Reputation
“All In One WP Security & Firewall” is much less famous than the other WordPress security plugins I’ve been testing. As of December 13, 2013 it has been downloaded 100,803 times. I would be thrilled if I were the plugin author, because that’s a lot of downloads; but with the leading security plugins boasting around a million downloads or more, this one has some serious catching up to do.
Reviews of this plugin have been very positive: it enjoys a 4.9 out of 5 star rating. As with all the other security plugins I’ve reviewed, I do begin the process by reading the one-star reviews. In this case, there is only one. The complaint in this case is something about how the plugin’s “cookie based brute force” feature stores a secret word in the .htaccess file. Apparently the reviewer had used his existing WordPress login password as the “secret word.” Tip: never reuse your passwords! Anyway, as another commenter pointed out, a properly configured web server will not permit visitors to casually inspect the contents of your .htaccess file. So this does not sound like cause for too much concern.
Installation
The download for “All In One WP Security & Firewall” version 3.1 is a lightweight 508 kilobytes. When unzipped and installed in my test environment, it takes up 1.85MB of disk space.
Now, let’s see what happens when I click the “Activate” link.

Good news! No errors, just a nice little “Plugin activated” message at the top of my screen. The plugin creates a “WP Security” menu at the bottom of the sidebar. I click that, and see…

Quite a stylish dashboard. It’s got a “Security Strength Meter” that looks like a speedometer. It rates a number of security considerations, assigning each one a point value, and then rating the total security strength of the website based on which points have been earned. On my initial load of the dashboard, my test site’s security strength is valued at 15 out of 395. Yes, I got 15 points because even in a test environment, I didn’t create an administrative user with the default username, “admin.”
Plugin testing & evaluation
What else is worth points? Let’s explore the various menu options.

User Accounts
I click the menu option for “User Accounts.” This is where I got my starting points, there is no user named “admin.” The User Accounts menu also has tabs for “Display name” and “Password.”
The “Password” tab does not test the strength of passwords already stored in the database, or provide a convenient interface for resetting your password; but it does evaluate the cryptographic strength of your password, if you type it in the provided box.

Unfortunately, the algorithm evaluating password strength is somewhat faulty; I typed in a very weak password, and was told that it was very strong. A stronger password tester is built into Daniel Convissor’s plugin, “Login Security Solution.”
Back to the plugin at hand, the Display Name tab on the User Accounts screen advises me that I should change the “Nickname” for my account, because otherwise an attacker will be able to easily find my username.

This is a valid concern, and I’ve seen logs from incidents where an attacker obviously tried a few default usernames, then looked at the site’s source code to find the real username. Unfortunately, I don’t believe the suggested solution is valid. I’ll show you why.

Here I am on the user profile editing screen for WordPress 3.8. As you can see, I have changed the display name and nickname for my user account.
Now I visit my test site’s homepage. I’m running a stock installation of the “Twenty Twelve” theme (sorry, WP team, but I simply can’t stand the clown-college lame headerbar on “Twenty Thirteen”). I select “Hello, World!” from recent posts. Interestingly, the “post meta” information is not displayed by default with this theme. It’s easy to find, though. I just hit Control+U and view the page source. I search for “author” and there it is, complete with a hypertext link to my author profile. If this section weren’t hidden with CSS, the visible text would say, “View all posts by nickname,” which is how I told WordPress to display my name publicly. But you see that the link to my author profile page clearly uses my login username, not my nickname.

My login username is still clearly available in the blog post’s HTML source code, and in the URL for the author page. So the plugin’s suggestion in this case, while a nice thought, is about as useful as changing your locks and then leaving the door open.
Personally, I think this is yet another security vulnerability in the WordPress architecture. I understand that WordPress is trying to create a user-friendly system, where all users must have unique login names, but some users could potentially share a nickname. Regardless, a vulnerability is a vulnerability. Perhaps someone should write a plugin that allows authors to more completely obfuscate their login username.
The point being, the plugin’s suggestion is well-meaning, but not particularly useful from a security perspective.
Settings
Moving right along, let’s check out the “Settings” menu.

Under “General Settings” we have options to back up the database; back up the root .htaccess file; and back up the site’s wp-config.php file. Then below that are options to disable security features or disable firewall rules, in the event of a system malfunction. (This assumes that your wp-admin will load, after a system malfunction…)
The .htaccess tab on the Settings menu has options to back up, restore, or view the contents of your site’s root .htaccess file. It does not have options to either directly edit the .htaccess file, or to install a default system of firewall rules. Those options are further down the menu, under “Firewall.”
Likewise, the wp-config.php tab is just for backing up, restoring, and viewing your current wp-config file.
Let’s get to some interesting stuff.
User Login
The “User Login” option screen is a “Limit Login Attempts” style IP-based lockout system, where an attacker who passes a certain threshold will be prevented from continuing to attempt to log in for a specified period of time. Unfortunately, this one is weak, because it does not include a permanent lockout feature. This means the attacker can come back an hour later and keep trying to brute force your password. Anyway, as I never get tired of saying, single-IP-based lockouts are becoming obsolete in the era of the distributed botnet. It’s true that you can go to the Blacklist Manager screen to permanently blacklist an IP address manually, if it gets repeatedly locked out.
But if the attacker is wielding a botnet of 90,000 computers, what’s the point? A better option is to ban all of Europe and Asia as well as any VPN, web host, or cloud-computing related network from accessing your site. Seriously, do you have any potential customers in Kazakhstan and Azerbaijan? No. The only visits you get from countries like these are attackers.
All of which is beside the point.
My other complaint about the “Login Lockdown” system is that it is not enabled by default. This is a very basic security system; it should be switched on when the plugin is activated. Granted, other security plugins have the same flaw; but just because they’re all wrong, does not make this all right.
Firewall
Let’s check out the firewall.

This is what I’m talking about. First, let’s test to see if activating the firewall will overwrite my existing placeholder rules in the site’s root .htaccess file.
So I check the box marked “Enable Basic Firewall Protection” and click “save.”
So far so good, no error messages. Let’s see what has happened to my .htaccess file.

The plugin has added four rules to the .htaccess file (and no, it did not overwrite my existing rules). The “Basic” rules deny all access to wp-config.php; deny all access to the .htaccess file (which should be denied anyway by default on a properly functioning server but I suppose you can’t be too careful); turn off the Server Signature; and limit the request body to 10MB, which I suppose could be useful in helping to prevent certain types of DDoS attacks. Even if you’re a graphic designer or print shop, you don’t want clients uploading a payload of this size; and most website owners are not print shops.
So the “Basic Firewall Settings” are pretty rudimentary. Let’s enable every single option on the “Additional Firewall Rules” tab.
This is better. I do feel like I have to do a lot of clicking to enable the rules I want; but these are good rules. Deny directory browsing on folders with no index file; deny requests via TRACE and TRACK; and forbid some query strings that could be used for remote file inclusion or certain SQL injection attacks. This includes a list of forbidden characters, which should be URL encoded in any legitimate request. The rules are good. My favorite one here is the one banning comment posting via proxy forwarders. While this would not block all spam comment submissions, it would help to forbid some of the most egregious comment spammers.
All right, and the next tab, “5G Blacklist Firewall Rules,” delivers what it promises. Check the box, hit save, and the plugin adds Jeff Starr’s highly respected 5G Blacklist security rules to your .htaccess file. The blacklist, available from the Perishable Press website, is an essential component of modern website security. It again forbids cross-site scripting, directory traversal, SQL injection, and remote file inclusion attacks.

Brute Force Prevention
The next tab on the Firewall screen is the “Brute Force Prevention” tab. Since brute force attacks are the most common attacks against WordPress installations, this is a topic of much interest to any WordPress website owner.
In this case I’m personally thinking about writing a plugin that will utilize the /wp-admin/admin-ajax.php file via an AJAX request; so I go ahead and check the box that says, “My site has a theme or plugins which use AJAX.” This would also be true of a site running Wordfence in parallel with this plugin.
Well, first I have to perform a cookie check, so I have to save this setting twice to enable it.
No, this feature is problematic. It appears to rely on a cookie stored in my browser to determine whether I have permission to access wp-login.php via secret URL redirect. I enable it in one browser, switch to another browser, type in the super-secret login URL, and get a 403 Forbidden message. That sounds like potential trouble.

I see what’s going on. When I visit the super secret URL, it doesn’t send me to wp-login.php. It sends me to
http://localhost/wp/wp-login.php?redirect_to=http%3A%2F%2Flocalhost%2Fwp%2Fwp-admin%2F&reauth=1
You see the problem? Sure you do, you’re sharp. The query string includes “http.” And any query string containing the keyword “http” is now forbidden by our firewall.
Other than that, the system works like a charm. In order to log in, you must first access the secret url.
If you’re accessing the login page from a browser that doesn’t already have the authentication cookie set, you have to access it via the secret query string link. Then you get the “Forbidden” message because the new URL has a redirect in the query string. So then you have to type in the actual location of the login page, and it loads fine.
It’s an interesting solution to the problem, and it’s not an idea I’ve seen before. Obviously there are some potential glitches when the redirect directive in the URL collides with existing deny rules; but overall this is a useful solution and a creative concept.
Filesystem security
Moving on, let’s visit the “Filesystem Security” screen. It allows you to set appropriate file permissions for your WordPress system resources. It requires a single click for each file or folder. This is much simpler than using an FTP client for the same purpose; and much more user-friendly than other plugins I’ve reviewed, which alert you of the problem without providing an easy way to fix it.
Also, I think 644 is a much more reasonable permissions setting for your .htaccess file than 444. When you set the permissions to 444, you can’t update the file yourself. And if you’re like me, you want to update your .htaccess file all the time. So that is a vote in this plugin’s favor.
Unfortunately, this feature isn’t working for me. I keep clicking the “set recommended permissions” for the .htaccess file, and I keep getting a message that the permissions were updated for my wp-config.php file. Actually it doesn’t matter which button I press. It keeps giving me a “success” message about wp-config.php, regardless of which file or folder I’m trying to change permissions for. Worse, even though I get the success message for wp-config.php, it continues to show that wp-config.php has the wrong permissions.
Giving the developer the benefit of the doubt, this could be because I’m running the system on Windows. Be that as it may, if I can’t verify that it works, then I can’t state that it works. Which is unfortunate, because I was starting to like this plugin. I might drop a line in the plugin’s support forum when I get time.
Just for giggles, I attempt this in a different test environment which is still running WordPress 3.7.1. I click “Set recommended permissions” for the .htaccess file, and I get an error, “Unable to change permissions for …wp-config.php!”
Regrettably this looks like an error in the plugin code logic, hopefully one that will be an easy fix for the plugin developer.
[ also available from BWPS ]
Database Security
The “Database Security” screen allows you to quickly change the table prefix for all your WordPress tables in your database. This is a recommended best practice, because it obscures what would otherwise be a known database table structure; so if you didn’t do it at setup, you might want to seriously consider doing it here.
Spam Prevention
The “Spam prevention” screen has two features. One is an additional .htaccess rule denying access to the comment posting script for bots that haven’t set your domain in the referrer header. The other adds a Captcha field to your site’s comment forms. My personal feeling is, if you run a small website, you’re better off just disabling comments altogether. I probably get one legitimate comment for every thousand or so spam comments; and akismet costs money if your blog is for a business.
Scanner
The “All in One WP Security & Firewall” plugin features a scanner similar to the one offered by “Better WP Security.” This scanner looks for changes to files in the WordPress core, and changes to plugin files. When a site is compromised, hackers often insert a “back door” into WordPress core files; so this type of scanner has a valid security purpose. It looks like this scanner works by storing an initial state of all the files in your system when you run the first scan: noting the location, file size, and last-modified file meta. Then when you run a subsequent scan, it compares the stored information to the current state to see if the files have changed. This is a simple, elegant solution to the problem of file change detection. It will also doubtless cause a host of false positives whenever you update your core or plugins or theme files. If you know in advance which files or directories are most likely to generate false positives, you can tell the plugin to ignore them, so you won’t have to wade through a whole bunch of notifications that are nothing to worry about.
Other Features
There’s a WHOIS lookup built right into the plugin, so you can look up an IP address and find out whether suspicious activity is coming from BingBot or from a genuine attacker. There’s a “Maintenance Mode” feature so you can shut down all traffic to your site in the event you suspect you’ve been breached.
Does not obscure login error messages by default
This plugin does not obscure login error messages by default.

The default WordPress login error messages are overly helpful. If someone is trying to brute-force your administrator password, it’s much better to let them waste their time trying to brute-force an account that doesn’t exist, rather than helpfully telling them to try a different username.
At first I thought the plugin did not have a mechanism for obscuring the WordPress login error messages at all. Eventually, I found the setting, buried deep in a menu. When the setting is enabled, the plugin will obscure those login error messages; but you have to find it first. You’ll find it at User Login > Login Lockdown > Login Lockdown Options > Display Generic Error Message.
System changes
OK so that about covers the features of the “All in One WP Security & Firewall” plugin. Let’s see what changes it has made to the system.
Filesystem changes
Like some of the other security plugins I’ve reviewed, “All in One WP Security & Firewall” creates a “backups” folder in the wp-content directory. This folder is named aiowps_backups. The idea is, if the plugin gets deleted, you’ll be able to easily restore it from the backup. The question is, if I delete the plugin on purpose, do I really want it to leave a bunch of files on my system? Plugin authors and end users sometimes have divergent views on this point.
Obviously the plugin also makes a number of changes to the website’s root .htaccess file as described above, there’s no need to repeat all that here.
Database changes
Most plugins make changes to the MySQL database. Let’s see what this plugin does.
New tables
This plugin creates four new tables in the database, three of which are related to login activity. You’ve got wp_aiowps_failed_logins, wp_aiowps_global_meta, wp_aiowps_login_activity, and wp_aiowps_login_lockdown.

Before we investigate the global meta table, I want to know why there’s a “login activity” table separate from the “failed logins” table.
This is interesting. When you successfully log in, the plugin notes your IP address, your browser’s user-agent, and the country you are located in (based on your IP address). That way, if someone else attempts to maybe steal your auth cookies via a man-in-the-middle attack, the plugin might be able to detect that they’re not you. (However, please note that I did not test this feature’s implementation.) The only thing that I don’t like about this, is that when you successfully log in, your actual login username is stored in plain text in this table’s user_login column. However, it’s not really important, since by default the same user_login name is stored in WordPress’s own wp_users table, again in plain text.
So, the global_meta table has an odd structure. Why would each row require 5 separate key/value pairs? Some investigation with the MySQL console reveals that meta_key1 is file_change_detection.

So far, only one row has been created. Of course, it turns out to be one of those incredibly long rows where a single meta_value entry (in this case, meta_value4) contains a bewilderingly long array of key/value pairs.
It’s not perhaps the way I would have designed this database table, but it works, so who am I to complain?
Changes to wp_options
This plugin also creates two new entries in the wp_options table. They are aiowpsec_db_version and aio_wp_security_configs. Fair enough.

Uninstalling
The final test of any plugin is how well it behaves when you tell it to go home.
So I deactivate the plugin. What happens if I try to log in?
To be clear, I first turned on the settings that require you to visit the login page from the super-secret URL. Now I deactivate the plugin. And with the plugin deactivated, I am still unable to access the login page without first visiting the super-secret URL.
The problem is, the plugin has been deactivated. So even if I DO visit the super-secret URL, I still can’t access the login page, because the plugin is not active to set the required authorization cookie. This is a problem.
Now I delete the plugin. This should hypothetically resolve the above.
But no, it is as I feared. Deleting the plugin does not delete the rules it added to the site’s root .htaccess file. That means if you enable the cookie-based brute force prevention tool, and then delete the plugin, you’ll never be able to log in again unless you first manually edit the .htaccess file and remove the relevant directives.
In fact, deleting the plugin did not affect the .htaccess file at all. Similarly, deleting the plugin did not delete the aiowps_backups folder.
Given that the .htaccess file was not cleaned, it comes as no surprise that the database tables were not removed either. All the tables created by this plugin upon installation remain in the database when the plugin is deleted by the administrator.
The same is true of the data written to the wp_options table. None of it is removed when the plugin is uninstalled.
Conclusion
I’ll tell you what I’m looking for. I’m looking for a single plugin that will secure a website against most common attacks with minimal setup. This plugin is close, but it’s not quite there.
- Does not obscure login error messages
- The “brute force prevention” feature relies on a redirect that conflicts with one of the deny rules in the .htaccess file
- The “change file permissions” feature does not work as expected
- The .htaccess rules are good, but enabling them all does require quite a few clicks on several different screens
- “Limit failed logins” is not enabled by default
- Password evaluation algorithm is weak
- When the plugin is deactivated, the “Brute Force Prevention” feature breaks the login page.
- The plugin does not clean up after itself at all when it is uninstalled by the user.
Many of these issues might be relatively easy to fix. I might bring them to the plugin author’s attention and see if I get a response. I like the plugin’s interface, and I like that this plugin does not have the sort of coding errors and excessive nags that I got from the last plugin I tested. With a couple of tweaks, this really could be an all-in-one security solution.
Next time: a whole lot of plugins compared.
