Protecting WordPress with Open Source Web Application Firewall ModSecurity

Protecting WordPress with Open Source Web Application Firewall ModSecurity

In this guide you will learn how to install and protect WordPress with the Open Source Web Application Firewall (WAF) ModSecurity. We will also install the latest protection rules from the OWASP Core Rule Set (CRS). A WAF is a great addition to the Cyber Security protection for your WordPress blog or website and can stop many zero-day attacks and known attacks, or as the project describes itself:

The CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten, with a minimum of false alerts.

This guide is written for the latest Ubuntu Linux LTS (Long Term Support) which is 20.04.3.

Installing ModSecurity and Core Rule Set

First step is to install modsecurtiy from the package repository:

sudo apt install libapache2-mod-security2

And it will look something like this if the above command is successfull:

WordPress ModSecurity Apache
Then we make sure that the module is really enabled:
sudo a2enmod security2

And also restart the Apache webserver:

sudo systemctl restart apache2

You can also verify that the module is loaded using this command: apache2ctl -M|grep security

Now we need to enable the blocking of Cyber Attacks in the ModSecurity module. This is not enabled by default so we need to change the SecRuleEngine config option:

sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

And then edit the file /etc/modsecurity/modsecurity.conf using your favorite editor such as vim, emacs or nano. You need to change the line:

SecRuleEngine DetectionOnly

to

SecRuleEngine On

That’s it regarding Apache and ModSecurity. Now we need to download and enable the latest Core Rule Set:

cd
git clone https://github.com/coreruleset/coreruleset.git
cd coreruleset
sudo mv crs-setup.conf.example /etc/modsecurity/crs-setup.conf
sudo mv rules/ /etc/modsecurity/

And it it goes well it would look something like this screenshot:

After this we will enable the rules in the configuration file and remove the old CRS. So the next step is to edit the file /etc/apache2/mods-enabled/security2.conf so it will look like this:

And then as the last step of enabling ModSecurity and the Core Rule Set, restart apache:

sudo systemctl restart apache2

ModSecurity WordPress tweaks

In order to get WordPress to work better with ModSecurity and the OWASP Core Rule Set (CRS) we need to make a few small tweaks. CRS has a variable named tx.crs_exclusions_wordpress and can be enabled depending on the URL of your WordPress installation. Edit the file crs-setup.conf and change the following lines:

# SecRule RESecAction \
#SecAction \
# "id:900130,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.crs_exclusions_cpanel=1,\
#  setvar:tx.crs_exclusions_dokuwiki=1,\
#  setvar:tx.crs_exclusions_drupal=1,\
#  setvar:tx.crs_exclusions_nextcloud=1,\
#  setvar:tx.crs_exclusions_phpbb=1,\
#  setvar:tx.crs_exclusions_phpmyadmin=1,\
#  setvar:tx.crs_exclusions_wordpress=1,\
#  setvar:tx.crs_exclusions_xenforo=1"

So it will look like this:

SecAction \
 "id:900130,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:tx.crs_exclusions_wordpress=1
#  setvar:tx.crs_exclusions_cpanel=1,\
#  setvar:tx.crs_exclusions_dokuwiki=1,\
#  setvar:tx.crs_exclusions_drupal=1,\
#  setvar:tx.crs_exclusions_nextcloud=1,\
#  setvar:tx.crs_exclusions_phpbb=1,\
#  setvar:tx.crs_exclusions_phpmyadmin=1,\
#  setvar:tx.crs_exclusions_wordpress=1,\
#  setvar:tx.crs_exclusions_xenforo=1"

Remember to reload the new rules by issuing a reload to the apache webserver:

sudo service apache2 reload

Important: Always remember to save more just than 14 days of logs. We recommend to save at least one year of logs, and this can be changed in the file: /etc/logrotate.d/apache2 and in this case we are saving weekly and 52 weeks (one year):

logrotate.d apache2

Problems and fixes

First problem we will run into is the following error:

Execution error - PCRE limits exceeded (-8)

And this error can be fixed by raising the following configuration option: SecPcreMatchLimit and SecPcreMatchLimitRecursion in the /etc/modsecurity/modsecurity.conf file. Set them to:

SecPcreMatchLimit 1000000
SecPcreMatchLimitRecursion 1000000

And the next error that will show up is when a file is being uploaded:

Access denied with code 403 (phase 2). Match of "eq 0" against "MULTIPART_UNMATCHED_BOUNDARY" required

This can be fixed by commeting out line 86 in the modsecurity.conf file, like this:

Also the following error is displayed in the logfile when the Theme Editor in WordPress is used:

Request body no files data length is larger than the configured limit

Update the file modsecurity.conf and change SecRequestBodyLimit to the value 6000000.

Also we need to whitelist a few IDs. Create the following file:

/etc/apache2/conf-enabled/whitelist.conf

Add the following lines:

<LocationMatch "/wp-admin/theme-editor.php">
  SecRuleRemoveById 300015 300016 300017 950907 950005 950006 960008 960011 960904 959006 980130
</LocationMatch>

<LocationMatch "/wp-admin/admin-ajax.php">
  SecRuleRemoveById 300015 300016 300017 950907 950005 950006 960008 960011 960904 959006 981173 980130
</LocationMatch>

Also remember to always run reload when changing the ModSecurity configuration and rules:

sudo systemctl reload apache2

Thats it! If you find any other error please comment below so we can help each other to make WordPress even more secure.

1 thought on “Protecting WordPress with Open Source Web Application Firewall ModSecurity”

  1. my question is where modsecurity should be installed, on the same server where wordpress is installed, or in a separate vps server ?

Leave a Comment

Your email address will not be published. Required fields are marked *