In this post I’ll explain how to secure a WordPress website. I get paid for system administration, so I’m familiar with how Internet works, protection, computers, systems etc. However, I’m not some “super-hacker”, nor am I expert for Linux based servers. All the information given here is “to the best of my knowledge”. Any additions, or corrections are welcome.
Note: I wrote a more general post about domain and website security. Might want to read that one first, before coming back to this post.
- Safe habits
- Hosting server / provider
- Domain registrar
- SSL/TLS certificates and encryption
- WordPress security
8.1. Disabling directory listing and protection from basic attacks
8.2. WordPress administrator and user accounts
8.3. Themes, plugins and WordPress core
8.4. Security plugins
8.6. Additional security edits
- Bad advice
If you google: “how to secure a WordPress website”, you will get thousands of pages. What I’ve noticed (again, disclamer: based on my knowledge and experience) is many provide wrong, or even (potentially) dangerous advice.
Here I’ll give a list of practices I’d recommend, with comments of some often given advice that is not good.
Important note: WRITE DOWN everything you do/change. That way, if something goes wrong, you will be able to revert back to when it worked and figure out how to fix it. Also, do one change at a time. Then test. Only after it’s confirmed to be working, move on to the next step.Otherwise you’ll have a problem to figure out what the problem is if something goes wrong.
First thing to note about security is that it’s like a chain – strong as much as its weakest link. It is not limited to software, antivirus, firewalls. Behaviour and habits are also very important. What good is the best alarm, if you leave the keys unattended? I like when things are explained to me using clear analogies, so will be using those myself in this text.
Each layer of protection introduces a certain amount of inconvenience. If you lock your house door, you need to take a key and unlock them to enter. Two locks is even safer, but take more time to lock and unlock. And so on.
In addition to that: 100% secure system is unusable – by definition. Imagine a bunker/safe with no windows, reinforced concrete walls and a thick steel door. That door needs some locking system for relatively convenient unlocking and entry for those authorized. That same system will be a security risk that can be hacked with enough knowledge, tools and effort. The only way to eliminate this risk 100% is to leave no doors, just reinforced concrete walls. That way, the bunker would have no security weak points, but would also be completely useless.
2. Safe habits
A short list of important things, that are not related only to WordPress, but still important with it as well:
- Use safe and secure computers (and smartphones) for logging in and working on the websites.
- Us a safe Internet connection. If on a public Wi-Fi, use a VPN. I use and recommend Windscribe VPN (my review link).
- Don’t leave saved login passwords in browsers and on devices. If you must, at least use LastPass (affiliate link). Although I’d recommend saving logins and passwords using KeePass, or similar program (compatible Mac KeePass client, and for Linux KeePass client – look for your distribution on the KeePass dowload page, or use your software manager).
- Before opening an email, check and confirm that it really is sent by those claiming to have sent it. Be especially cautious if clicking on a link in a suspiciously looking email. Post about safe email handling.
- Torrent, or porn related websites often have viruses. Might want to use a virtual machine for browsing those.
Bad security habits are like afore mentioned leaving keys in a public place (unattended).
I would also recommend reading my post about two factor authentication as a good security measure on the Internet.
Yes, it might sound obvious, but the first link, computer that you use for connecting to the website, should be secure. With updated security patches if using Windows, and a good firewall and antivirus. Good free one is 360 Total Security (affiliate link).
Make sure your browser is updated. My favorite for this is Yandex, but it’s definitely worth checking what a website looks like in Mozilla and Chrome, as well as the mobile phones.
Not sure if it’s worth mentioning that it’s best not to log into your computer with administrative privileges, unless un/installing some programs, or changing some system settings. This annoys most people (having to log off, then log in as administrator to install something), but it is a good and simple protection from viruses and malware installation.
Using a compromised computer is like shouting to a neighbour, so that everyone can hear: “the keys are under the vase!”
4. Hosting server / provider
Many people (not all) start with cheap(est) hosting. Then problems arise, after which some start looking for “good, even if it costs more”. Well set up and secured hosting server is an important link in the chain – but still only that: a link. If other aspects (that I’ll explain) are not secure, hosting by itself can’t guarantee website safety. However, if the hosting server is not properly setup, all else is in vain. Though this goes for most other security aspects (website security chain links).
For those using VPS, or dedicated servers, unless you really know what you are doing (in which case you probably needn’t read this post at all and know more than I do), consider getting a managed server hosting.
Shared and reseller hosting packages are anyhow put on servers maintained by the hosting company.
Any way: choose hosting provider with good reputation, quality of service and security. My hosting recommendations.
Most of good DDoS and brute force attack protection is done at the hosting server firewall and WAF level.
Using unsafe, not well protected hosting server is like a ground floor house with glass doors and windows – easy to enter using simple brute force.
5. Domain registrar
I’ve often seen this situation:
Website is hosted with a poor quality hosting provider while the domain is registered… with the same hosting provider. Many hosting providers offer free domain registration if you use their hosting, but only for the first year. Renewal prices can later be higher than market average. There’s also the question how well the domain is protected and whether you are free to migrate registration to another registrar.
I use and recommend Namecheap (affiliate link) domain registrar. They offer free whois protection, domain migration locking and 2 factor security using a mobile phone number. Well designed user interface, mobile app – I like it all. A bit less practical, but cheaper option I also use is Porkbun (affiliate link).
Whichever registrar you choose, make sure your domain is renewed in time. Best done for two, or more years in advance for domains that you intend on keeping. Domain renewal can usually be done automatically by most domain registrars (unless disabled by the user). Still, credit card charging problems can occur, or auto-renewal could malfunction for any reason. So it is safer to keep track of domain registration expiry and if it is in the current year, prolong it for at least one more.
Google seems to like “seeing” a domain registered for longer, giving a fraction of a ranking bonus to websites it considers safe and reliable (unconfirmed rumour that I think is not to be 100% disregarded).
Not tracking your domain expiry dates is like not tracking your tax debts – you can end up without a house.
Bad and unsafe domain registrar is like not copyright protecting your brand – you could loose it and spend a lot of time and hassle to get it back.
In a separate post I explained what are domain and nameservers, and how to protect domain registrar account.
6. SSL/TLS certificates and encryption
There are still websites that don’t use https, or at least allow access over non-encrypted http protocol as well. Unless you have a very good reason not to, do implement and enforce https protocol for your website. Same goes for FTP, e-mail and other channels of communication and website access.
LetsEncrypt certificates are free and easy to install (one click installs with most hosting providers) – in a separate post I explained the pros and cons of free vs paid SSL/TLS certificates.
When connecting to your website using the unprotected http protocol, it is easy to see all the data sent and received, including usernames and passwords. Https should be enforced on your server, not leaving the visitors (or yourself) a choice of using the unencrypted http.
Accessing website without https and TLS encryption is like leaving confidential documents visibly on a library table, so anyone interested enough could sneak a peak.
SSL/TLS encryption is based on the principle of asymmetric encryption.
I wrote about enforcing https in the post about redirections. With separate posts explaining how to install SSL/TLS in cPanel and DirectAdmin SSL/TLS installation.
Unlike SSL/TLS and https protocol, HSTS is something I think is still not recommended for a large majority of websites. What is HSTS?
Simply put: it is listing your website for using https only, (practically) permanently. In case of any certificate problems, or a need to access the website using a protocol without encryption, your website will simply be inaccessible through non encrypted http.
A good article that explains the problem in detail: OPINION – Dangerous Web Security Features.
HSTS is like having a doorman in an apartment building that leads all your visitors to the flat number 42. If, for any reason, you change the flat, visitors will still be lead to the door number 42 and only there.
This is why before implementing HSTS all things should be considered and well thought through. Unless your website is a “high profile target” (banking, very popular, large e-commerce site etc.), it is, still, better to avoid HSTS – it can create more problems than it solves, requiring hiring an expert to solve them.
Before dealing with WordPress itself, another thing worth mentioning is Cloudflare. In addition to offering DNS and rudimentary CDN features within the free package, it also offers a level of SQL injection and DDoS attack protection (I find the DNS function convenient when migrating websites).
Also, like other means of protection, Cloudflare adds a level of complexity. For example: complications when using Engintron and Nginx server. So you must weigh the pros and cons for yourself. I personally like Cloudflare and think it’s worth the bother, at least the way it works for now.
In a separate article I give a detailed, step-by-step instructions on how to configure Cloudflare for WordPress (improving speed + security).
8. WordPress security
For this I’ve read the greatest number of bad and counterproductive advice. Previously explained aspects are at least just as important for WordPress website security though – do implement them.
Fact: most WordPress website hacks come from bad, or not updated plugins, or themes.
Order in which I’ll give security tweaks and recommendations is “from the bottom” so to speak: from the server level, over the WordPress core, to the plugin and theme level. Let’s start.
8.1. Disabling directory listing and protection from basic attacks
If hackers can’t see the contents of your website directory and file lists, they will have more problems in finding vulnerabilities.
This kind of security is called “security by obscurity”. Some experts disregard this kind of security as too naive. Others rely on it too much. My opinion: if it doesn’t introduce problems, or complications, then every way of making hackers’ job harder is good and should be implemented. The last bolded part will be referred to later, when I discuss some counterproductive security measures.
Other useful security option is preventing MIME-sniffing and cross site scripting (XSS) attacks.
Unless this has already been done, edit .htaccess file from the root directory of WordPress installation by adding the following code at the top (copy/pasting the code below will do the job):
# GREMLIN (custom) CHANGES # preventing directory listing Options -Indexes # clickjacking attack protection Header always append X-Frame-Options SAMEORIGIN # MIME sniffing protection Header set X-Content-Type-Options nosniff # XSS protection Header set X-XSS-Protection "1; mode=block" # END OF GREMLIN (custom) CHANGES
Other security setups should have been done by the hosting provider. If they haven’t, there’s a list on Sucuri’s WordPress hardening page.
Advanced options for limiting edit, upload and access rights are given on the official WordPress page. They are not to be disregarded, although not all will work with all the websites and themes – do test.
8.2. WordPress administrator and user accounts
Something very similar to this I see too often:
Administrator account on the website should be hard to guess. For example, username “Averel”. So that it doesn’t have any connection with the website, author, or the topic that website deals with. Definitely don’t use “admin”, or “administrator”.
Password should be over 15 characters long, contain at least one Capital letter, number and special character (!, %, $ etc.). Same goes for the password of the database user (set on the hosting server).
Author accounts, whose user names are public on the site, should not have administrative rights. And also have very strong passwords. All the website work that can be done using author privileges should be done using that username and password – don’t log in as an administrator, unless it’s needed.
Another “catch” that goes for both administrator and author/editor accounts, is to have your login username (set during the WordPress installation) be hard to guess and different from your name as shown on the website, publicly.
Edit administrator’s and author’s logins in the database:
By default, WordPress exposes a user’s login username (no matter whether the user is an Administrator, or “just” an “Author”):
You should change the login username in the database – WordPress will keep showing the old one, even after you edit this (fortunately). How to do that?
Open the database using PhpMyAdmin, or a similar tool. DirectAdmin and cPanel have PhpMyAdmin installed, so you can just click on it:
Now you’ll get a list of all the users. It would be wise to edit the login usernames of all the Administrators, Editors and Authors. Do that by clicking on “Edit” next to the user:
And that’s it as far as editing the login usernames goes. 🙂
If subscribing to the website is allowed, make sure that the default account privileges are “Subscriber.”
8.3. Themes, plugins and WordPress core
Security flaws in themes, plugins and not-updated WordPress versions are the most common culprits for hacked and infected websites.
Update them all regularly (but before that do a backup and try them on a test website version first, just in case).
Choose well written and tested themes and plugins. I already wrote about choosing good plugins, the same principle goes for choosing a good theme.
Delete any themes or plugins that are not used. Why leave a potential security risk (backdoor) if it’s not needed for the website to function?
A website with a list of found vulnerabilities of WordPress plugins: WPscan vulnerability database. There you can search for plugins you (intend to) use and see if they have any un-patched vulnerabilities.
8.4. Security plugins
Of all the security plugins, only Sucuri (as far as I know), in paid version, prevents attackers from reaching the site (with a firewall and WAF).
Others kick in when the attacker has already reached the site. In free versions, they offer some protection and website scanning for viruses. I like WordFence. It enables (like most others) setting a limit of the number of login attempts before blocking the attacker’s IP address if it’s exceeded (for a user set period). If all the “live” traffic reporting options and automatic website scans are disabled, it doesn’t put too much load on the server, while providing some extra protection.
WordFence keeps stats of detected attack attempts – IP addresses, attempted login usernames etc. It can also be set to immediately block IP address of anyone trying to log in with “admin” username for example.
I wrote a separate post explaining how to configure WordFence (and discussing the plugin in great detail, along with some benchmarks).
If comments are allowed on the website, there are plugins (like WordPress Captcha Plugin by Captcha Bank) that prevent spam using subscriber comments. WordPress Discussion options allow for limiting comments only to registered and logged in subscribers. If the option of subscribers having to get at least one approved comment before their comments are no longer held for moderation is enabled, the amount of spam is put to minimum.
This is less security related – more to do with website reputation and reducing needless server load.
8.6. Additional security edits
Preventing clickjacking attacks:
Open wp-config.php file (located in the root directory where WordPress is installed on the server) and add the following code:
This can also be done by adding some code to functions.php of the child theme, but in case of changing a theme, it will need to be done again (for the new theme), so I’d not use that implementation.
The third way to do this is by editing .htaccess file (with Apache servers). You will need to have mod_headers enabled by your hosting provider in order to be allowed to do this. Code, that is added right at the beginning of the file is the following (for Apache servers this is already given in chapter 8.1. code example):
# GREMLIN (custom) CHANGES <IfModule mod_headers.c> Header always append X-Frame-Options SAMEORIGIN </IfModule> # END OF GREMLIN (custom) CHANGES
For NGINX servers:
add_header X-Frame-Options "SAMEORIGIN" always;
Clear website’s cache, open the website in a browser, press F12, then re-load the website and see the headers:
Preventing XSS (Cross Site Scripting) attacks:
The following code should be added to wp-config.php. This will tell the browsers to accept cookies only from the website and only using https protocol. If your website is using http, omit the middle (second) line:
@ini_set('session.cookie_httponly', true); @ini_set('session.cookie_secure', true); @ini_set('session.use_only_cookies', true);
9. Bad advice
This has somewhat influenced me to write this post in the first place (along with providing advice/instructions to novices for securing their WordPress websites, without having to repeat the same thing for 100 times). All the above described security measures are not implemented on many websites, but many people who have “skipped” most of those “steps” have asked me how to implement the following “famous” security measures:
- Hiding the login URL address from the default wp-admin, wp-login.
- Changing the WordPress database prefix, to something other than wp_.
Why do I think this is bad advice? I “touched” the reasons in chapter 8.1.
- They can create complications (right away, which is a better option, or in the future) with functioning of some themes and plugins.
- At the same time, they can, even changed, still be figured out by an attacker.
- If all the other mentioned security measures are implemented, changing login URL and database prefix are not really needed.
- If all the other security policies aren’t implemented, changing login URL and database prefix won’t help.
Oh, yes, almost forgot: same goes for hiding the WordPress version, but that is a lot less “popular” measure based on my experience.
Your WordPress website will be hacked/infected. My site will be hacked/infected. It’s not a matter of “if”, but “when?” WordPress is far from the most optimizied and safest platform. What then and what is all this for?
First: good security policy can help to make website problems rare, not regular.
Second: good security policy enables spotting the problems in time, as soon as possible.
Third: backups. Make backups regularly, after every content change and before any plugin/theme/WordPress update. Keep at least one backup copy of each previous month, at least for a year back. Why?
Say you make backups on a weekly basis, keeping the last two backups. If a virus infection is noticed only after a month, you will not have a backup copy from before the infection. Removing viruses from a website is hard and expensive task, with a questionable outcome.
That’s about it. I’ll be updating this post (like all the others) with new information as it comes. Hope it will help. Any additions, corrections and suggestions are wellcome.