Server protection

Server protection

This is the product of original research conducted by our company, offering a quite thorough protection against a plethora of known threats when enabled. This feature is based on the tenet that nothing executes on your site unless you allowed it to. By blocking access to site elements (media files, JavaScript, CSS and PHP files) it makes it extremely hard —but not outright impossible— for an attacker to hack your site, even if he manages to exploit a security vulnerability to upload malicious PHP code to your site. Additionally, it will deny direct access to resources not designed to be directly accessible from the web, such as translation files, which are usually used by attackers to find out which version of WordPress you are running on your site to tailor an attack to your site. On the downside, you have to explicitly enable access to some plugins' PHP files which are designed to be called directly from the web and not through WordPress' main file, index.php.

Do note that enabling this feature will kill the functionality of some extensions which create arbitrarily named PHP files throughout your site, e.g. in subdirectories of wp-content/plugins. In our humble opinion the security risk of having your site unprotected outweighs the benefits of such solutions.

Before describing what each option does, a small explanation of how the protection works is in order. The protection code in the generated .htaccess file blocks direct web access to all files. WordPress's standard "entry point" or "main" file, index.php, is automatically exempt from this rule. However, your site also contains images, media, CSS and Javascript files inside certain directories. For each of the back-end and front-end protection we need a set of directories where such files are allowed and the file extensions of those files. These are what those options are all about. The default settings contain the most common file types you'd expect to find on a site and the standard WordPress directories where they should be located. You only have to tweak them if you want to add more file extensions or have such static files in locations other than the default.

Site protection

Disables direct access to most resources, except those in the exceptions lists. It is generally recommended to turn it on to enhance the protection of your site.

File extensions allowed

The extensions of files which allowed to pass through the server protection filter. Place one file extension per line, without the dot. For example, if you want to allow access to all PDF files you have to type in pdf on a new line of this list. Do note that file extensions are case-sensitive. This means that PDF, Pdf, pdf and pDF are four different file extensions as far as your web server is concerned. As a rule of thumb, type in the extensions in lowercase and make sure that the extensions of the files you upload are also in lowercase.

File extensions added here are allowed inside WordPress' default directories (wp-includes and wp-content). Moreover, only files with these extensions are allowed in the directories placed under the “Directories where only files with allowed extensions will be accessible” option (see below).

Disable client-side risky behavior in static content

The files with extensions matching “File extensions”are, generally speaking, static files. However, some kinds of static files may contain client-side, dynamic content. For example, HTML and SVG files can contain JavaScript which executes on your browser. This kind of client-side, dynamic content can pose a security risk. For example, an attacker can upload a malicious HTML or SVG file which steals your login cookie and sends it to the attacker who can now impersonate you on your site, allowing them to take it over.

When you enable this option the .htaccess Maker sends a Content-Security-Policy header for these files which prevents them from executing any embedded client-side code in them.

If you do have certain files or folders with static files that absolutely need executable, embedded, client-side code please add them to one of the three Exceptions features described further below. Any explicitly allowed files or folders will be exempt from the “Disable client-side risky behavior in static content”.

The following section is Exceptions. This allows specific files or all files in specific directories to pass through the Server Protection filter without further questions. This is required for several reasons. For starters, WordPress' core features depend on direct access to files. Some plugins also need to directly access PHP files, without passing them through WordPress' index.php. One such example is Akeeba Backup Professional's restore.php used in the integrated restoration feature, as it would be impossible to use the index.php of a site which is in a state of flux while the restoration is underway. Finally, you may have a third party script which doesn't install as a WordPress plugin. The Server Protection feature would normally block access to it and you still need a way around this limitation. So here we have those workarounds:

Files which will always be made accessible

Place one file per line which should be exempt from filtering, therefore accessible directly from the web. The default settings only include WordPress core files which need to be accessed directly.

[Note]Note

If you are using ManageWP you will also need to add wp-load.php in the list. This file is not in the list by default because using wp-load.php instead of index.php to load WordPress is wrong. Moreover, WordPress does have a JSON API application, and wp-cron.php which can both be used to return pristine API output and are more suitable to this task than abusing wp-load.php.

You do not need to add anything that is located wp-admin. That folder is always allowed direct access. If you want to best protect your site we recommend that you use the Password Protect wp-admin feature of Admin Tools to apply a server-level password protection to your wp-admin folder. This will very efficiently protect it from hackers.

Directories where only files with allowed extensions will be accessible

Place one directory per line. Only files with extensions matching the “File extensions allowed” will be accessible in these directories. Any other file will NOT be allowed to be accessed over the web.

This is useful for folders which have non-executable files such as wp-content/uploads.

Directories where all files except .php will be accessible

Place one directory per line. All files in these directories, except those with a .php extension, will be allowed to be accessed directly from the web. Please note that this option differs from the one above. Directories in this list allow all file extensions, not just the ones listed in “File extensions allowed”. Only files with .php and similar extensions (such as .phps, .php5 and so on) are blocked.

Directories where all files including .php will be accessible

Place one directory per line. This option should be used as sparingly as possible. Each and every directory placed in this list is no longer protected by Server Protection and can be potentially used as an entry point to hacking your site. As far as we know there are only three cases when its use is even marginally justifiable:

  • If you have installed another WordPress, Joomla!, phpBB, or any other PHP application in a subdirectory of your site. For example, if you are trying to restore a copy of your site inside a directory named test in your site's root you have to add test to this list. This is the one and only usage scenario which doesn't compromise your site's security.

  • Some themes and theme frameworks may wrap their CSS and JavaScript inside PHP files in order to deliver them compressed to your browser. While this is a valid technique, it's possible that the list of PHP files is too big to track down and include in the first list of the Exceptions section. In this case you may consider putting the template subdirectory containing those files in this list.

  • Some plugins generate .php files with arbitrary file names and expect them to be directly accessible from the web. This is insecure because you cannot tell which files are legitimate and which are suspicious just by looking at their filenames. Hackers understand that and know of these plugins, therefore they will try to hide their hacking scripts inside these folders: it's hiding a tree inside a forest.

    Please note that this practice is dangerous. If you want to allow it it's your site and your risk assessment. Just don't come back and wonder why Admin Tools didn't protect you when it's you who has decided to cut a hole in the fence :)

In order to figure out which custom exceptions you need to add on your site, take a look at the How to determine which exceptions are required section.

[Warning]Warning

Windows users beware! Do not use Windows' path separator (the backslash - \) to separate directories! We are talking about directories as they appear in URLs, so you should always use the URL path separator (forward slash - /) in those settings. In other words some/long/path is correct, some\long\path is WRONG.

How to determine which exceptions are required

After applying the Server Protection script you may notice that some of your extensions do no longer work properly or, even worse, at all. Sometimes your site may even look like something's missing or like CSS and Javascript no longer loads. Don't be afraid and don't rush into turning off the Server Protection. Determining which exceptions are required is easy and takes only a few minutes of your time. On the upside, once you determine them on one site you can reuse them on all sites having that plugin installed. You will quickly end up with your "master" exceptions list which you'll be able to apply to all of your sites without a second thought.

In the following example we are going to use Google Chrome to detect access issues on a site. Similar tools are built-in in other major browsers, such as Firefox, Opera, Safari, Edge and Internet Explorer 8 or later.

A typical indication that something went wrong is that CSS has gone missing or an action does not complete.

In order to figure out what is going wrong, we have to find out which of the files referenced by the page are throwing a 404 error (this means that they are filtered out by Server Protection), their naming pattern and location. Provided that you are using Chrome open up the Developer Tools pane by typing CTRL-SHIFT-I while viewing that broken page. Click on the Network tab. Reload the page. A list of files the browser tried to access appears.

Go through this list and look for items in red. Look at the Status column. If you have a 404 or 403 you have located the files which probably have the problem.

Click on each red file. The right hand part of the window changes to display some debugging info about that file. Make sure the Headers tab is selected. The interesting part is the request URL which tells you where that file came from.

First, make sure these files really do exist. If they don't exist it's a legitimate 404 (not found) error and you can't do much about it. It the files do exist they are being blocked by our .htaccess file. Try adding the file path relative to your site's root (NOT the file URL!) in the Files which will always be made accessible list in the .htaccess Maker. Then save and create .htaccess file and reload the page.If you repeat the process you'll see that this file now loads correctly.