17 December 2021

This article looks at Apache’s Files and FilesMatch directives. Both are used to allow or deny access to files on your website.

Managing access to specific files

The Files directive specifies a file, and inside the directive you define one or more actions. You can use this to deny access to a file. For instance, you might have a phpinfo.php file that contains lots of details about your website’s PHP configuration. You can block access to the file with this rule:

<Files "phpinfo.php">
  Require all denied
</Files>

Here, I used the same syntax I used in the article about denying access to an IP address. If you want to allow only a single IP address to access the file then you can add a Require ip rule:

<Files "phpinfo.php">
  Require all denied
  Require ip 1.2.3.4
</Files>

You can do the same for other sensitive files, such as the wp-login.php and xmlrpc.php files on WordPress websites.

Matching files using regular expressions

The FilesMatch directive lets you specify files using a regular expression. A good example is the WordPress Toolkit rule that denies access to PHP scripts in the wp-content/uploads directory:

<Directory "/home/example/public_html/wp-content/uploads">
  <FilesMatch \.php$>
    Require all denied
  </FilesMatch>
</Directory>

Note that the FilesMatch directive is nested inside a Directory tag. That means the rule is only valid inside the uploads directory. The regular expression is simply \.php$. As you can probably guess, that matches files with the extension .php.

If you are not familiar with regular expressions, the dot needs to be escaped because it has a special meaning: it matches any single character. The stroke escapes the dot, so that it is interpreted as a literal dot. The dollar sign is an anchor that denotes the end of the string.

In the same way you can deny access to specific PHP files. For instance, this rule denies access to wp-login.php and xmlrpc.php but allows access for the IP address 1.2.3.4:

<FilesMatch (wp-login|xmlrpc)\.php$>
  Require all denied
  Require ip 1.2.3.4
</FilesMatch>