6 steps to secure WordPress against hacking and hacker attacks.

Learn how to secure your WordPress installation from hacking and hacker attacks by following these 6 steps to control access and eliminate vulnerabilities.

An example of how my website could look, if WordPress had been hacked and defaced by a hacker or automated bot network driven hacker toolkit.

Why are WordPress websites hacked?

Hacking of WordPress and other websites are done by hackers for many reasons, which not only include gaining access to valuable information, but also to claim bitcoin or money for ransom, eliminate competition, spread illegal software, spread political messages, perform negative search engine optimization or abuse your website network bandwidth in larger coordinated hacker attacks against other sites. Only rarely is hacking done just for the fun of it, but when it is, it is usually about putting up a picture, which is known as defacing.

More often than not, hacking are not actually done by a single hacker, but by an automated attack, that is executed by a hacker, that initiated a password cracking tool from a hacking toolkit, which controls a large coordinated bot network. In that case, your WordPress installation just happened to use a specific vulnerability, that this attack exploits. An example of such a vulnerability could be a security hole in a plugin, that has not been updated.

How to check, if WordPress are being hacked.

When WordPress is under attack, the website might become slow, unresponsive or unavailable. You might also see walls in network traffic. However, there is a better way to check, if your website are being submitted to hacker attacks or has been hacked.

Each time a user visits your WordPress website, or a hacking attempt is made, the web server, that hosts your website, logs any request. Each log entry includes a time stamp, the IP address of the visitor or hacker network, the targeted WordPress file and the error code from the web server. It can include more information, such as the user agent, which is the browser finger print of the visitor.

In the example below the log shows, that a Google bot visited the website and requested the sitemap, which was served. This is not a hacker attempt, so blocking this IP address could be a costly mistake, because Google would no longer be able to index your website.

66.249.66.36 - - [26/Feb/2021:23:04:19 +0100] "GET /sitemap_index.xml HTTP/1.1" 200 770 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

If your website is under attack, you will discover patterns of repetitive requests to WordPress login page, WordPress plugins or other parts of WordPress, from suspicious network addresses. Store the log, so you can investigate, which part of your WordPress is being targeted and who is responsible for the attack.

Example of a brute force attack on WordPress login page.

Below is an example of a brute force attempt against the login page of a WordPress website. A hacker is running an automated piece of hacker software, that are trying different usernames and passwords from a long list of hacked accounts, common passwords from a dictionary and randomly generated passwords.

If your server does not identify this attack, then a brute force attack like this can run for days, weeks or months – and eventually obtain access. It is in an attack like this, that the length and difficulty of your password is important.

By looking in the web server log, you will notice a pattern of repeated login attempts. In this example the web server was not secured, so you will notice, that each request are followed by HTTP error code 200, which means, that the request was completed.

91.200.12.18 - - [07/Apr/2016:07:26:41 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:42 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:42 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:43 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:43 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:44 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:45 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:45 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:46 +0200] "POST /wp-login.php HTTP/1.1" 200 3568
91.200.12.18 - - [07/Apr/2016:07:26:47 +0200] "POST /wp-login.php HTTP/1.1" 200 3568

A quick look-up in WHOIS reveals, that this attack was done from a single IP address, that was registered to a local internet registry in Ukraine. It is not uncommon to learn, that scammer and hacker attacks originate from Russia and Ukraine.

# whois 91.200.12.18
inetnum:        91.200.12.0 - 91.200.15.255
org:            ORG-PS152-RIPE
country:        UA
mnt-by:         GLUBINA-MNT
created:        2007-09-21T12:32:02Z
org-type:       LIR
address:        Gvardeyskay, 14 , K. 1
address:        Severodonetsk
phone:          +380661922248

Further research confirmed, that these IP addresses were used by scammers and hackers, and was reported and registered in real-time black-hole lists (RBLs) and other abuse databases, that servers can use to identify and block hacker attacks.

Step 1: Restrict access to the WordPress login page.

Restrict access to the login page, dashboard and administration part of WordPress, so only administrators and editors of WordPress can access from known networks. This is called access control. This is not only a very strong protection from hacker attacks, but it also takes off the server load, that your site endures, while being submitted to brute force attacks.

This is best done by configuring the website, which is known as a virtual host, in the web server configuration. Below is an example of such protection in Apache. First the main directory of WordPress is secured. Replace the path with the path of your website and set your own IP addresses in the bracketed variables.

<Directory ".../www.example.com">
  <Files "xmlrpc.php">
    Require all denied
    Require ip ${admin}
  </Files>
   <Files "wp-cron.php">
    Require all denied
    Require ip ${server}
  </Files>
   <Files "wp-login.php">
    Require all denied
    Require ip ${admin}
  </Files>
</Directory>

Then the login part of WordPress is secured.

<Directory ".../www.example.com/wp-admin">
  <Files "admin-ajax.php">
    Require all granted
  </Files>
  Require all denied
  Require ip ${admin}
</Directory>

If this is not possible for you, then an alternative is to restrict access to the WordPress login page by using a WordPress plugin, that offers access control with the use of IP address white listing. Some plugins also offer limits for login attempts, two factor authentication (2FA) and other security measurements.

Consider country wide blocking or redirection.

You might consider going as far as blocking entire countries, that are not part of the market, that your website are targeted for. This is known as country wide blocking and is done by loading aggregated access control lists of IP addresses, that are used in countries, that should be blocked. These country lists are available and maintained by security sites on the internet.

The lists are either loaded by the web server or by the server firewall. An alternative to this is to use the lists, that are offered by WordPress plugins, but these are not as effective.

An alternative to blocking these countries are redirecting them to another site, that you might have dedicated for those and thereby segmenting your traffic into different sites.

Step 2: Use strong passwords for WordPress, database and web host.

The time, it takes for a brute force attack to be successful, depends on the strength of your passwords and the response time of your website. The strength is not only about the length of your passwords, but also, that it has never been used on other sites, that could have been hacked or otherwise compromised.

Use a password generator and a password manager.

WordPress comes with a built-in password generator, which is recommended, because it generates passwords, that are unlikely to be cracked by brute force attacks within reasonable time. You can also use another password generator or generate your own.

The fact, that the passwords are long and complex, should not be a problem, because you should be using a password manager, which is either a part of your browser or a separate piece of software, that stores and handles your passwords securily.

Examples of strong passwords.

The passwords below are examples of strong passwords, that were generated by different password generators. The first one was generated by Mozilla Firefox. The next by WordPress. The last by a custom password generator, based on makepasswd, made by myself. These are just examples and should not be used. Note, how none of them contains dictionary words.

4bveHNGLgx6znip
@&g8@E%k^WE(#zzj^u&Mb)gJ
E8!0k=mC(g=839aAs)kSdfZ)V(2Fg(m_&3TjW/k0

Implement strong passwords everywhere.

It is not only the WordPress user account, you should secure with a strong password. You should also ensure, that the passwords to your WordPress devices, WordPress database and web host are protected by strong passwords as well. These passwords should also be unique and never used anywhere else. WordPress devices has separate passwords within the user accounts and are known as application passwords.

Finally you should go through the registered users accounts in your WordPress installation. Each one should use a secure password. Users, that are no longer active, should be logged out and deleted.

Step 3: Disable and delete unused and unnecessary themes and plugins.

Each theme and plugin for WordPress are vulnerable to hacker attacks. If they are no longer used, and no longer updated, they will become a day by day increasing target for hacker attacks. Your entire WordPress website will be at risk. For this reason, the use of themes and plugins should be kept at an absolute minimum and each theme and plugin should come from a trusted source and be actively maintained and supported by its developers.

Step 4: Update WordPress, themes and plugins regularly.

As times goes by, new features and software developments are introduced to WordPress, themes and plugins. As mentioned before, failing to keep software updated makes your website vulnerable to hacking. You should, for that reason, update your WordPress installation, and its themes and plugins, regularly. You can either have the server do this automatically, but if you are running a professional site, that offers a critical server, I recommend, that updating and testing is performed manually on a regular basis.

WordPress depends on the programming language PHP. You will also want to make sure, that you are using a PHP version, that is recommended by WordPress. WordPress also depends on a database server, such as MySQL. You will also want to make sure, that the version of this server is up to date and secure.

Step 5: Install a web application firewall.

While not necessary, you can consider installing a web application firewall, such as the Wordfence plugin for WordPress. If step 1 is not possible for you, this option becomes more important, because it is able to handle brute force attacks, identify security related issues with your WordPress installation and perform a number of security related measures to mature your website against hacker attacks.

However, you should be aware, that a web application firewall like Wordfence is not a real firewall. The reason for that is, that a real firewall runs on a network level and can effectively block hacker attacks and take off the server load from these attacks.

Step 6: Backup WordPress and its database contents regularly.

You should, at all times, have a backups of your WordPress installation. You should not rely on your website host to backup your site alone, but also have your own independent backups. If you have your own backup, you will be able to restore from even a worst case scenario, where your website and cloud backup has been lost.

A backup of your WordPress installation includes themes, plugins, uploaded files and configuration files. It should also include encryption certificates, analytics configuration files and other files, you might have. Because WordPress stores your posts and pages in a database, such as MySQL, then your backup must also include the contents of your WordPress database.

Creating backups of WordPress should be completely automated. Either by scheduling a script on your web server or by using another piece of software, that automates your backup process. You should keep a number of backups, so you are able to restore your website to a specific date. I recommend, that you have the web server dump your WordPress database and export a backup of your WordPress directory and database dump file to your external backup repository daily.

In the example below, a web server has been scheduled in crontab to run a script backup-wordpress, that dumps the WordPress database and exports the WordPress installation to an external backup repository each day at midnight while maintaining a number of rolling backups.

# Min    Hour   MDay  Month  WDay  User      Command
  0      0      *     *      *     root      /root/bin/backup-wordpress

If WordPress has been hacked and you need help.

If your WordPress website has been hacked, and you need urgent help to restore your website and secure your website from new attacks, then follow these steps at once.

  1. Secure your backups, so they are not over-written by ransom ware or bad data.
  2. Take your website offline immediately. Not only to protect your website from further damage, but also to stop spreading illegal software or being part of a larger coordinated hacker attack.
  3. Change all your passwords. This includes all WordPress users, the WordPress database and the web host.
  4. Obtain a copy of the web server log file. This will be used to investigate, what kind of hacker attack, your website has been submitted to, for how long, the extent of damage and other information.
  5. Make a backup of your WordPress installation. This might not seem important, if you know, that you have a backup elsewhere, but this will provide further insight into the kind of hacker attack, that your WordPress installation has been submitted to.
  6. Make a backup of your database content.
  7. Contact me at or directly. Please include a link to a copy of the log file.

How to build a profitable game plan for cashgame poker.

If you enjoy playing a nice game of cashgame poker at the local casino or your favorite online poker site, but also would like to make some profit, while doing so, then you will have to build a profitable game plan for the specific game, you will be playing.

Find the best casino or online poker site.

The PokerStars client and cashgame lobby shows, that the NL10 player pool has 44 tables running and a total of 74.296 players in total.

Your first consideration will be the casino or online poker site, that you will be playing at. If you have a choice, you might want to place your action, where you have the best advantage. This advantage is made of lots of elements, such as the player pool and environment.

Set the right bankroll management plan.

This simulation of variance shows, that even though this player has a good win rate of 4 bb/100, there is a risk of experiencing bad variance with a magnitude of 30 buy-ins over 25.000 hands.

If you plan on making a long term profit, then the size of your bankroll has to be sufficient, so you are protected against the variation and downswings, that is a part of the game. This will strike early or later. I recommend at least 25 buy-ins of the stake, you will be playing, which can reduce your risk of ruin to less than 5%. This depends on your skills and win rate. Read more about this in Variance and downswing in poker.

Prepare ranges for preflop play.

I open pocket kings from early position and 4bet squeeze in a fullring NL10 cashgame on PokerStars in 2021.

Prepare a well defined set of ranges, that you will be comfortable playing, and, that you know, you have played profitably. You might want to think about the expected player pool tendencies and use this information to prepare a tight and aggressive set of open ranges, 3bet ranges and 4bet ranges. You might want to tighten up or adjust slightly, if you will be moving up and want to compensate for your initial lack of information about the player pool tendencies.

Plan your actions for flop, turn and river play.

I check pocket aces to the aggressive fish, that, as expected, goes all-in on this flop, that brings a scare card like this king. Continuation betting here would be a mistake. If this player was a passive fish, I should bet.

Prepare a plan for your flop, turn and river play. This is more important, when you will be playing the small stakes and higher. You will want to think about, which hands, you will be betting vs. certain players on certain board types. You will also take into consideration, whether you are in or out of position. You might want to have a neat balance between value and bluffs for every street. For this to work, you will need to be able to profile your opponents and hand read, so you know, when you have equity to bet for value and when you have bluff equity to bet as a bluff.

Manage your time, so your game plan stays strong.

Make a routine, that ensures, that you have a good balance between studying poker, playing poker, reviewing key hands and analyzing your lines. All of which ensures, that your game plan stays updated and profitable. You should also ensure, that your mental and physical health is strong. It might not directly be a part of your game plan, but the execution of your game plan rely on it.

February cashgame poker challenge: 20K hands and $400.

Inspired by a poker friend, I have taken on a mutual February cashgame poker challenge with the goal of playing 20.000 hands at NL10 with a profit of $400. I will be playing fullring NL10 on PokerStars.

The PokerStars client and cashgame lobby shows, that the NL10 player pool has 44 tables running and a total of 74.296 players in total.

Time management.

There is 4 weeks in this month, which is 5.000 hands per month to complete the total 20.000 hands. PokerStars only allows 4 tables, which plays about 300 hands per hour, which means 17 hours per week for this challenge. I will probably not be able to play the full amount of hands, because of that, but I will try.

Strategy to beat NL10.

The strategy, I will be using, will assume, that the players are mainly level 1 and 2 players, and generally on the passive side, which I will exploit by playing quite simple tight and aggressive player style, that I will adjust to individual player styles of my opponents in terms of value to bluff ratio, bet sizes and lines. I will bet and raise more against passive fish and check and call more against aggressive fish. You can read more about this in my post Poker player profiling and color coding.

I face a minimum 3bet from an aggressive fish and 4bet with pocket aces. This player can not hand read, so I expect him to call.
I check pocket aces to the aggressive fish, that, as expected, goes all-in on this flop, that brings a scare card like this king. Continuation betting here would be a mistake. If this player was a passive fish, I should bet.

I will only expect very few good and strong level 3 players. I will expect, that these players will quickly recognize my level and play straight forward against me with a value or give-up mindset. For that reason, their tendencies against me will be different than against other players and I should not level myself into being deceived away from that.

Focus areas.

My biggest challenge will be adapting to the crazy fish, that exist on these stakes, as they will play their hands in surprising lines and are generally hard or impossible to read. They do not use preflop charts and does not know how their hand performs in relation to their opponent. It is very easy for a player like me to level myself into either putting them on strong made hands, that makes sense to me, or putting them on bluffs, that they are not capable of running.

Tracking progress and results.

I will track all played hands in PokerTracker and update the results after each week. When the challenge in complete, I will also run a some of my sample analysis filters and present pool tendencies.

Result.

I had to abort the challenge after about a week due to lack of time, which I also feared would be the case. My strategy for NL10 turned out to be relaxed, solid and profitable with a win rate of 18,71 bb per 100 hands. If I assume, that I could hold a win rate of 10 bb per 100 hands for the 20K hands, I would have completed the challenge and reached the goal.

The graph from PokerTracker looks solid and shows a win rate at 18,71 bb per 100 hands over 5.557 hands.

I was mostly value oriented. I only ran a few bluffs, which mainly was solid ones like nut flush blockers and gut shots. There was more passive fish than expected. I did not notice a single level 3 player.