START here

How to secure a WordPress website

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.

Contents:

  1. Introduction
  2. Safe habits
  3. Computer
  4. Hosting server / provider
  5. Domain registrar
  6. SSL/TLS certificates and encryption
    6.1. HSTS
  7. Cloudflare
  8. 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.5. Comments
    8.6. Additional security edits
  9. Bad advice
  10. Conclusion


1. Introduction

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).
    Update, November 2023: KeePassXC is my favourite KeePass software now, and it is available for Linux, Windows, and Mac:
    https://keepassxc.org/download/
  • 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.


3. Computer

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. I think that Malwarebytes in its paid version is very good (it is what I like and use), and it works wonderfully alongside Windows Defender.

A good free antivirus is 360 Total Security. It keeps your computer protected from viruses quite well (I’ve used it a lot). Note that it is Chinese software, so for all the folks who fear “being tracked by the Chinese government,” I suggest the above-noted Malwarebytes (it is better, but not free).
Of course, if you use a smartphone, social networks, and pay with a card, you are being tracked by the US government – you know that? 🙂

Make sure your browser is updated. I use Safari (on Apple stuff) and Chrome (on Linux and Windows), but it’s definitely worth checking what a website looks like in Mozilla and Edge, 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).
Update August 2023:
I’ve switched almost completely over to Porkbun. It’s good, and has lower prices.

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.

6.1. HSTS

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.


7. Cloudflare

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).

Cloudflare offers some other neat features for WordPress security, all for free:


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:
username: admin
password: admin123

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”):

Login username of the article's author is shown in the bottom-left corner here
The login username of the article’s author is shown in the bottom-left corner here
(I just hovered the mouse over the name)
Picture 1

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:

cPanel (left) and DirectAdmin (right) PhpMyAdmin icons
cPanel (left) and DirectAdmin (right) PhpMyAdmin icons
– Just click on it. 🙂
Picture 2
Editing WordPress users
Editing WordPress users
Click on the database you wish to edit (1)
Then click on the “users” table
Picture 3

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:

Opening a WordPress user "Edit" options in PhpMyAdmin
Opening a WordPress user “Edit” options in PhpMyAdmin
Picture 4
Enter a new login username, that is nothing like the "display_name" or "user_nicename"
Enter a new login username, that is nothing like the “display_name” or “user_nicename” (1)
Click on “Go” after that (2)
Picture 5

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).

8.5. Comments

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:

header('X-Frame-Options: SAMEORIGIN');
Adding the code to wp-config.php
Adding the code to wp-config.php
Picture 1

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:

Check whether the x-frame-options have been updated, it should show "SAMEORIGIN"
Check whether the x-frame-options have been updated, it should show “SAMEORIGIN”
Picture 2

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.

Bottom line:

  • 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.


10. Conclusion

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.


Please use the BikeGremlin.net forum for any comments or questions.

If you've found any errors or lacking information in the article(s) - please let me know by commenting on the BikeGremlin forum.
You can comment anonymously (by registering with any name/nickname), but I think it is good to publicly document all the article additions (and especially corrections) - even if their author chooses to remain anonymous.

Skip to content