Your WordPress install can be as secure or insecure as you want. Learn which five things are the most important when it comes to security.
Concerns and complaints about WordPress security are nothing new.
If you need a CMS and happen to consult a service provider that is not into WordPress, security is the number one con you’ll hear about. Does that mean everyone should drop WordPress and switch to static site generators or a headless CMS?
No, because just like every truth in life, this one also has many sides.
Is WordPress highly insecure?
Let’s take a look at some huge websites that were built on WordPress:
The New Yorker
So, what makes these companies–with absurdly deep pockets and a mind-boggling workforce–not switch from WordPress? If you think the answer is legacy code, think again: for these names, data security and public image are infinitely more important than a simple migration that will cost (I’m estimating) less than $200,000.
Surely their engineers know what they’re doing and see no fundamental, unsolvable security issues with WordPress?
Even I have the good fortune of managing a WordPress install that sees 3.5-4 million visitors a month. The total number of security breaches in the last eight years? Zero!
So . . . is WordPress secure?
I’m sorry if it seems like trolling, but here’s my answer:
I say so because, like every truth in life, it’s complicated. To arrive at a legitimate answer, we must first understand that WordPress (or any prebuilt CMS, for that matter) isn’t like a cupboard you stick somewhere permanently and be done with it.
It’s a complex piece of software with many dependencies:
PHP, which is the language it’s built with
A publicly visible machine that hosts the install
The web server used to handle visitors (Apache, Nginx, etc.)
The database being used (MySQL/MariaDB)
Themes (bundles of PHP, CS, and JS files)
Plugins (bundles of PHP, CS and JS files)
And many more, depending on how much your installation aims to accomplish
In other words, a security breach at any of these seams will be termed a WordPress breach.
If the server’s root password was admin123 and it got compromised, is it WordPress security flaw?
If the PHP version had a security vulnerability, or if the new plugin you purchased and installed contained a glaring security hole; and so on. To summarize: A subsystem fails, and it’s a WordPress security failure.
As an aside, please also don’t let this give you the impression that PHP, MySQL, and Apache are not secure. Every piece of software has vulnerabilities, the count of which is staggering in the case of open-source (because it’s available for everyone to see and analyze).
What we learn from all this exercise is this:
Nothing is secure or insecure on its own. It’s the different components used that form the links in the chain, the chain, of course, being as strong as the weakest of them. Historically, the “not secure” label of WordPress was a combination of old PHP versions, shared hosting, and adding plugins/themes from untrusted sources.
At the same time, some pretty common oversights make your WordPress installation vulnerable to those who know how to exploit them and are determined. And that is what this post is about. So without further ado (and circular arguments), let’s get started.
Top WordPress loopholes that hackers can exploit
The WordPress table prefix
The famous 5-minute-install is the best thing to happen to WordPress, but like all install wizards, it makes us lazy and leaves things at default.
This means the default prefix for your WordPress tables is wp_, resulting in table names that anyone can guess:
Now, consider an attack known as SQL Injection, where malicious database queries are cleverly inserted and made to run inside WordPress (please note — this is by no means a WordPress/PHP-exclusive attack).
While WordPress has built-in mechanisms to handle these types of attacks, nobody can guarantee that it won’t happen.
So if somehow, some way, the attacker manages to run a query like DROP TABLE wp_users; DROP TABLE wp_posts;, all your accounts, profiles, and posts will be wiped out in an instant with no chance for recovery (unless you have a backup scheme in place, but even then, you’re bound to lose data since the last backup).
Simply changing the prefix during the install is a big deal (which takes zero effort).
Something random like sdg21g34_ is recommended because it’s nonsense and hard to guess (the longer the prefix, the better). The best part is that this prefix need not be memorable; the prefix is something WordPress will save, and you’ll never have to worry about it ever again (just like you don’t worry about the default wp_ prefix!).
The default login URL
How do you know a website is running on WordPress? One of the tell-tale signs is that you see the WordPress login page when you add “/wp-login.php” to the website address.
As an example, let’s take my website (http://ankushthakur.com). Is it on WordPress? Well, go ahead and add the login part. If you’re feeling too lazy, here’s what happens:
Once this much is known, the attacker can rub their hands in glee and start applying nasty tricks from their Bag-O’-Doom on an alphabetical basis. Poor me!
The solution is to change the default login URL and give it only to those people who are trusted.
For example, this website is also on WordPress, but if you visit http://geekflare.com/wp-login.php, all you’ll get is a deep disappointment. The login URL is hidden and is only known to the admins?
Changing the login URL isn’t rocket science, either. Just grab this plugin.
Congratulations, you just added another layer of frustrating security against brute force attacks.
The PHP and web server version
We’ve already discussed that every piece of software ever written (and being written) is full of bugs waiting to be exploited.
The same goes for PHP.
Even if you’re using the latest version of PHP, you can’t be sure what vulnerabilities exist and might get discovered overnight. The solution is to hide a particular header sent by your web server (never heard of headers? read this!) when a browser connects with it: x-powered-by.
Here’s what it looks like if you check the dev tools of your favorite browser:
As we can see here, the website is telling us that it’s running on Apache 2.4 and using PHP version 5.4.16.
Now, that’s already a ton of information we’re passing along for no reason, helping the attacker narrow down their choice of tools.
These (and similar) headers need to be hidden.
Fortunately, it can be done quickly; unfortunately, sophisticated technical knowledge is needed as you’ll need to dive into the guts of the system and mess with important files. Therefore, my advice is to ask your website hosting provider to do this for you; if they don’t see if a consultant can get it done, though this will depend largely on your website host whether their setup has such possibilities or not.
If it doesn’t work, it might be time to switch hosting providers or move to a VPS and hire a consultant for security and administration concerns.
Is it worth it? Only you can decide that. 🙂
Oh, and if you want to nerd out on security headers, here’s your fix!
Number of login attempts
One of the oldest tricks in the hacker’s handbook is the so-called Dictionary Attack.
The idea is that you try a ridiculously large number (millions, if possible) of combinations for a password unless one of them succeeds. Since computers are lightning-fast at what they do, such a foolish scheme is sensible and can yield results in a reasonable time.
One common (and extremely effective) defense has been to add a delay before showing the error. This makes the recipient wait, which means if it’s a script employed by a hacker, it will take too long to finish. That’s the reason why your computer or favorite app bounces a little and then says, “Oops, the wrong password!”.
Anyway, the point is, that you should limit the number of login attempts for your WordPress site.
Beyond a set number of tries (say, five), the account should get locked and should be recoverable only through the account holder’s email.
Thankfully, getting this done is a cakewalk if you come across a nice plugin.
HTTP vs. HTTPS
The SSL certificate your vendor has been pestering you about is more important than you might think.
It’s not merely a reputation tool to show a green lock icon in the browser that says “Secure”; rather, getting an SSL certificate installed and forcing all URLs to work on “https” is alone enough to take your website from being an open book to a cryptic scroll.
Another way to intercept the traffic flowing from your computer to the server is packet sniffing, which is a passive form of data collection and doesn’t even need to take pains to position itself in the middle.
For sites that run over plain “HTTP,” the person intercepting the network traffic, your passwords and credit card numbers appear clear, plain text.
But once you install an SSL certificate and all URLs get converted to “https,” this sensitive information shows up as gibberish that only the server can decrypt. In other words, don’t sweat those few dollars a year. 🙂
Will be getting these five things under control secure your website nicely?
No, not at all. As countless security articles say, you’re never 100% secure, but it’s possible to eliminate a large class of these problems with reasonable effort. You may consider using SUCURI cloud WAF to protect your sites holistically.
I write about, around, and for the developer ecosystem. Recommendations, tutorials, technical discussions — whatever I publish, I try my best to cut through confusion and fluff, and provide actionable answers based on personal experience… read more