Published by on June 11, 2019 • 0 Comments • Lire en Français

Did you know that 100% of WordPress sites have a .htaccess configuration file?

Indeed, WordPress automatically creates it during installation to include the permalink settings of your website.

When you go to Settings > Permalinks to choose your permalink settings (usually Post Name), the .htaccess file is modified.

Nevertheless, it should be noticed that this file can play a much more important role.

Stunned guy

The .htaccess file is a configuration file that WordPress uses for Apache web servers, the software your server uses to run (*).

The contents of this file will give instructions to Apache to make the server behave in a certain way.

Thanks to the .htaccess file, you will be able to:

  • Improve your site security
  • Increase the load speed
  • Set up redirects
  • Limit spam
  • And even make little jokes 🙂

Interested, are you?

So keep reading, you won't be disappointed! Here is the program:

Warning

Be careful, some hosts only run on the NGINX server. This is the case with Flywheel, for example.

How does the .htaccess files work in WordPress?

A website may have several.htaccess files.

First of all, there is the main.htaccess file, which is located at the root of the site. The root of a website is where WordPress files are located (wp-admin, wp-includes and wp-content folders plus a few other files).

The content of the main.htaccess file will have an influence on the whole site.

Other.htaccess files can be created in subdirectories. In WordPress' case, one can be placed in the wp-admin or wp-content/uploads directory for example.

Secondary.htaccess files will influence the directories in which they are located as well as their subdirectories.

If we imagine that there is a.htaccess file in wp-content/uploads, the uploads directory and all its subdirectories will be impacted by what will be defined in the.htaccess file.

Be cautious!

Attention aux yeux, ça peut piquer

Customizing the code of an.htaccess file is quite simple (especially with the snippets I'll give you later in this article), but you shouldn't go ahead holus-bolus!

Before any change, save the initial content of your.htaccess file. To do this, you can:

  • Duplicate the.htaccess file on your server into an initial.htaccess-file
  • Copy the contents of the file to a text file on your computer

If a problem occurs, you can easily restore the original content.

To make changes, follow the following procedure:

  • Open the file in your code editor
  • Add your inclusions in the file
  • Save it all
  • Update your site to see if everything is going well

Updating your site is very important because you need to be sure that the added code is not a problem.

In general, an “Internal Server Error” will be displayed on the screen if something goes wrong:

Internal Server Error

In this case, cancel your changes and save again. Everything should be fine.

Sometimes, it happens that some hosting providers do not accept this or that code in the.htaccess file….

You have to deal with it.

Contact your hosting provider's support for more information. Hopefully, only a slight modification is needed to make it work.

Notice

Are you a victim of a WordPress error, like the typical and widespread 500 error? WPMarmite offers you a complete guide to solving the main ones.

How to create a .htaccess file in WordPress?

Logically, your site should have at least one.htaccess file: the one located in the root directory of your site. You can change it using your code editor.

There are other solutions like the Htaccess Editor plugin to modify it directly from WordPress. But in case of an issue, you will have to go through FTP and your code editor, so you might as well do it directly.

If you need to add a.htaccess file to a subdirectory, follow these instructions:

Create a.htaccess file from your computer:

  • Create a new text file and name it htaccess.txt
  • Edit it as you wish
  • Send it to the root of your server
  • Rename it to.htaccess

Create an.htaccess file directly from your server:

  • Right-click in the directory where it should be located
  • Add a new file and name it.htaccess
  • Edit it with your code editor (Notepad+++, Coda, SublimeText or the one that suits you best).

Congratulations, you now know what a .htaccess file is, and how to create it.

Now that it is ready, discover how to customize it in 5 different places:

  • To the root of your server
  • In wp-admin
  • In wp-includes
  • In wp-content
  • In wp-content/uploads

Come on, let's start right away with the root of the site. You will see, this will be the most consistent piece.

Notice

As in all computer languages, the.htaccess file allows you to include comments. In our case, just add the # symbol at the beginning of the line and it will be ignored. This is very useful to remember what lines of code do. You will have the opportunity to see comments in the examples in this article.

.htaccess file located in the root directory of your site

If your installation is OK, you will find an.htaccess file in the root directory of your site. It will contain the following code:

# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

# WordPress
Default code of the WordPress.htaccess file

If you use WordPress in multi-site mode, the default code of the.htaccess file will be different. This will not apply to you in most cases.

Now that you have located this file, you will be able to enrich its content with the snippets below, to get specific things. This may concern safety, but not only.

Be careful not to include any code between the comments # BEGIN WordPress and # END WordPress as it is possible that this code may be modified in some cases.

Information

Warning : Backup your original.htaccess file before making any changes. You must be able to go back in case of a problem !

Disable directory browsing

By default, if you try to access the directories of a site, the server will display them. The formatting will look like this:

Fichiers et répertoires visibles de WordPress

Too easy for potential hackers, ain't it? The fact that they can see the files on your site will help them attack it easily. Insert the following code in your.htaccess file to protect your site:

# Désactivate the display of contents of rédirectories
Options All -Indexes

It's also possible to use this code to prevent directories from being listed:

# Alternative pour empêcher le listing des rédirectories
IndexIgnore *

Hide server information

For some hosting providers, the pages displayed may contain information about the server. This information can give information to potential hackers.

It's therefore better to hide them with the following code:

# Mask the information of server
ServerSignature Off

Enable symbolic link tracking

It's maybe all Chinese to you but it is important to insert this line of code in your main.htaccess file.

# Activation du suivi des liens symboliques
Options +FollowSymLinks

Thanks to this, your server will be able to follow what are called symbolic links, i.e. shortcuts.

Set your server to the right time

This is not really important but if your server is located abroad, you can tell it to set itself to your time zone with this line of code:

# Choix du fuseau horaire
SetEnv TZ Europe/Paris

Define the default character encoding

The following code is used to define the character encoding of text and HTML files as UTF-8.

# Encoding by défaut des fichiers textes et HTML
AddDefaultCharset UTF-8

Protect the wp-config.php file

The configuration file of your site (wp-config.php) contains the credentials to connect to the database. This is the most sensitive file on your site. It will clearly be the target of potential hackers. You can protect it by adding this code to the main.htaccess file:

# Protéger le fichier wp-config.php
<files wp-config.php>
order allow,deny
deny from all
</files>

Protect the .htaccess file itself

Just like the wp-config.php file, the.htaccess file must be protected to the maximum. To do this, insert this code:

# Protéger les fichiers .htaccess et .htpasswds
<Files ~ ~ "^.*\.([Hh]][Tt]][AaPaP])">
order allow,deny
deny from all
satisfaction all
</Files>

Restrict spam comments

If you have a blog, you know this as well as I do: spam comments is a real pain.

Fortunately, there is a trick to protect yourself directly in the.htaccess file. This is not a miracle solution, but combined with the Akismet plugin, the majority of spam comments should be filtered.

#  Éviter le spam de commentaires
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_METHOD} POST
rewriteCond %{REQUEST_URI} .wp-comments-post\.php*
RewriteCond %{HTTP_REFERER} !.monsite.com.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) ^http::///%{REMOTE_ADDR}/$ [R=3D301,L]
</IfModule>

Don't forget to change mywebsite.com to your domain name.

Avoid the discovery of an author's ID

Even if you use a complex user ID, it can still be discovered.

Of course, I guess you don't already display it publicly with your theme (it can happen) 😉

Try typing monsite.com/?author=x by replacing x with 1 for the administrator or ID of one of your authors. If you are not protected, you will be redirected to a page such as monsite.com/author/idenfiant_auteur.

That's how you find an ID in two seconds. From there, all you have to do is guess your password.

To protect yourself from this technique, use the following code:

# Éviter que l'on décover l'identifiant d'un auteur
# Merci à Jean-Michel Silone of Group Facebook WP-Secure https://www.facebook.com/groups/wp.security/
<IfModule mod_rewrite.c>
RewriteCond %{QUERY_STRING} ^author=([0-9]*)
RewriteRule .* - [F
</IfModule>

Thanks to Jean-Michel from the Facebook WP-Secure group for the tip.

Disable image hotlinking

Once you have added images to your site (for example, in a post), anyone can copy the URL of one of your images and display it on his website.

We could say that this is not so serious but if for some reason a very popular site grabs your image and displays it on one of its pages, requests will be made on your server.

Hotlinking can slow down your website and exceed your bandwidth limit. If your website is installed on a small shared server, your host may not like it because resources are limited.

To avoid the problem, insert and customize this code in your.htaccess file:

# Désactivate le hotlinking de vos images
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?:://(www\.)?monsite.com [NC]
RewriteRule \.(jpg|jpeg|png|png|gif)$ http:////fakeimg.pl/400x200/?text=Pas_images [NC,R,L]
Replace monsite.com with your domain name

To allow some sites to display your images, use the following code:

Replace monsite.com, monsite2.com and monsite3.com by the domains of your choice

You can also customize the image that will be displayed instead of the requested image. I added something simple but you can be cheekier 😉

Ban IP addresses

If you have noticed some IPs trying to connect a little too often to your site administration (for example with Login Lockdown plugin), you can get rid of them by blocking their IP address.

You also have the possibility to retrieve the IP addresses of spam commenters, to ban them from your site.

This solution is not definitive, because your attacker may change his IP address. But it may work for the least talented people.

# Bannir une address IP
<Limit GET POST>
order allow,deny
deny from xxx.xxx.xxx.xxx.xxx
allow from all
</Limit>
Replace xxx.xxx.xxx.xxx.xxx by the IP address to be banned

Block visitors from certain sites

If you realize that a non-compliant site links to you and you do not want visitors to this site to access your site, use this code:

# Empêcher les visiteurs de ces sites d'accèséder au votre
<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{HTTP_REFER} monsite1.com [NC,OR]
 RewriteCond %{HTTP_REFERER} monsite2.com [NC,OR]
 RewriteRule .* - [F]
</ifModule>
Replace monsite1.com and monsite2.com with the sites of your choice

Redirect visitors from one site to another

To go further than the previous tip, you can refer visitors from some sites to another site.

I might as well tell you that you could have a lot of fun doing that. Here is the code to use:

# Redireiger les visitors venant site vers un other
RewriteEngine on
RewriteCond %{HTTP_REFER} sitesource\.com/
RewriteRule ^(.*)$ http:///www.sitedestination.com [R=301,L]
Replace the source and destination sites with those of your choice

Set up redirects

The.htaccess file allows you to do redirects. This is very useful to redirect a few pages . But if you want to create a lot of redirects, I recommend the Redirection plugin.

Here is how to create redirects in the.htaccess file:

# Redirection d'une page quel
Redirect 301 /anciennepage/ http://www.monsite.com/nouvellepage


# Redirection of a new catégorie (with rename of category en category)
Redirect 301 /category/technology/ http:///www.monsite.com/categorie/techno/

Redirect the URL without www to www

When setting up a site, one of the priority actions to be taken is to redirect the site without www to the version with www (or vice versa).

If you do the test the next time you create a site, you will find that the two addresses do not necessarily refer to your site.

In some cases, your host automatically takes care of it, or it must be activated via the host's administration.

If you need to do this manually, use the following code by replacing mywebsite.com with your website URL:

# Redirection du site sans www vers www
RewriteEngine On
RewriteCond %{HTTP_HOST} ^monsite.com [NC]
RewriteRule ^(.*)$ http://www.monsite.com/$1 [L,R=301]
Replace monsite.com with your domain name

Redirect the www URL to the one without www

On the other hand, if you don't want www in front of your site's name (as for WPMarmite), it is possible to redirect to the version without www.

Insert the following code in the .htaccess file:

Replace monsite.com with your domain name

Warning: Do not use this code with the previous one otherwise your site will suffer from a redirect loop (because the version without www will redirect to the version with www which will redirect to the version without www, etc.)

Redirect to HTTPS

If you have set up an SSL certificate on your website to move from HTTP to HTTPS, you must be sure that all your visitors are browsing the secure version of your website.

Otherwise, sensitive information could be recovered by hackers (e.g. personal or bank data).

Use the following code to move your entire site to HTTPS:

# Redirection vers HTTPS 
RewriteCond      %{SERVER_PORT} ^80$
RewriteRule      ^(.*)$ https:///%{SERVER_NAME}%{REQUEST_URI} [L,R]

Force the download of specific files

When you want to download a file from a website, your browser sometimes tries to open it to display it.

Personally, I find this convenient for PDF files – however, it is very unpleasant for other types of files.

Insert the following code so that your visitors can directly download the files with these extensions (modify them as you wish):

Create a custom maintenance page

To create a maintenance page, you can use the following code:

# Page de de maintenance
RewriteEngine on
RewriteCond %{REQUEST_URI} !%2Maintenance.html$
RewriteCond %%{REMOTE_ADDR} !^xxx\.xxx\.xxx\.xxx
RewriteRule $  /maintenance.html [R=302,L]

For this to work, you must:

  • Create a maintenance .html file with content indicating that the site is being maintained.
  • Add your IP address in line 4 (keeping the “\”) to allow you to access the site (discover your IP address on this website).

When the maintenance is finished, put “#” in front of each line to comment them.

Enable caching

The.htaccess file allows you to cache some files on your site in your visitors' browser for faster load time.

Indeed, the browser will not need to re-download the files in its caching system.

To do this, insert the following code:

# Mise en cache des fichiers in le navigateur
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"


ExpiresByType text/html "access plus 0 AExpiresByType " text/xml  AexpiresByType appfont-ttf "access plus 1 month month"
ExpiresByType font/opentype "access plus 1 month month""
ExpiresByType plus Application/x-font-woff2 "access plus 1 month month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month month"


ExpiresByType image/jpg  "access plus 1 month"AExpiresByType  Axpires image 1 month"
ExpiresByType image/gif "access plus 1 monthshockwave-flash "access plus 1 week"
ExpiresByType image/x-icon  "access plus 1 week"

</IfModule>

# En-têtes
Header unset ETag
FileETag None


<ifModule mod_headers.c>   
<filesMatch "\.(ico|jpe?gg|png|gif|swf)$">   
     Header set Cache-Control  "public"  
/ilesMatch>  
<filesMatch "\.(css)$$">    
     Header set Cache-Control  "public"  
</ilesMatch>  
<filesMatch "\.(js)$$">   
     Header set Cache-Control  "private"  
</ilesMatch>  
<filesMatch "\.(x?html?|php)$">      Header set Cache-Control Cache-Control  "private, must-revalidate"
</ilesMatch>
</ifModule>

Caching of files will be effective for the time specified for each file type or until the visitor clears his caching system.

Tip

To speed up your site with caching, I recommend using the premium WP Rocket plugin. Simple and quick to configure, it is perfect for WordPress beginners.

Enable compression

In addition to everything we have seen so far, it is possible to compress some resources before they are transferred from the server to the browser.

And when I say file compression, I mean faster loading page time. I therefore recommend that you implement this code to give your site a boost:

Disable access to some scripts

To work, WordPress uses scripts located in the wp-includes directory. However there is no reason to access it directly. Use this code to limit access:

# Block use of certain scripts
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
rewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^^./]+[\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]

You can find out more in the codex.

Protection against file injection

Hackers may attempt to send files to your server to take control of your site. To prevent them to do so, you can include this code in your.htaccess file:

Protection against other threats

On Facebook, Richard told me that it was possible to protect yourself from “clickjacking” and other threats by adding a few lines in the.htaccess file.

For your information, clickjacking is a technique that makes it possible to make a visitor believe that he is on your site when this is not the case thanks to frame or iframe tags.

The following code protects you from clickjacking, fights other threats and blocks content in the event of an XSS attack.

# Protections  diverses (XSS, clickjacking and MIME-Type sniffing)
<ifModule mod_headers.c>
Header set X-XSS-Protection  "1; mode=block"
Header always append X-Frame-Options SAMEORIGIN
Header set X-Content-Type-Options: "nosniff”
</ifModule>

.htaccess in wp-admin

wp-admin is the den of your site. The place where you go to write posts, configure your menus, set your theme and much more.

It goes without saying that no unauthorized persons should enter this sanctuary.

Here is what you can do to harden security with a.htaccess file that you will have placed in the wp-admin folder of your site.

Limit access to site administration

Only people with the listed IPs will be able to access the wp-admin folder. Rather convenient to prevent strangers from connecting to your site (even if they have the right password).

<Limit GET POST PUT>
order deny,allow
deny from all
# IP Alex
allow from xxx.xxx.xxx.xxx.xxx
# IP of Nico
allow from xxx.xxx.xxx.xxx
# IP of other point ofaccès
allow from xxx.xxx.xxx.xxx.xxx

</Limit>
 

Add a second authentication

When you connect to the administration of a WordPress site, you use a username and a password. Well, it is possible to add a second one thanks to the.htaccess file and another file.

First, create a file named.htpasswd in the wp-admin directory and insert a couple of username and password.

If you need to create several users, repeat the operation and add the new ID/password pair within a new line.

For example, you can get this kind of file:

pastacode lang=”apacheconf” message=”Fictitious content of a file.htpasswd” highlight=”” provider=”manual” manual=”alex%3AieS547B1UxY8M%0Anico%3ArSqEJf0SeTlRs”/]

Then insert the following code into the.htaccess file:

# Second authentication for administration

<Files admin-ajax.php>
Order allow,deny
Allow from all
Satisfy any 

</Files>

AuthName "Connection à l administration"
AuthType Basic
AuthUserFile "/chemin/plet/verse/le/ilehtpasswd"


Require valid-user

The sensitive point of this manipulation is to enter the full path of the.htpasswd file. To find it for sure, create an info.php file and insert the following code:

Place the file info.php in wp-admin

Go to yourwebsite.com/wp-admin/info.php and you will get the real path of the.htpasswd file to place in the.htaccess file. Delete theinfo.php file once you have obtained the right path.

Update: If you insert this code as it is, AJAX requests will no longer work. 

If you have understood everything I just mentioned, you should have double authentication ready to access your WordPress admin.

Come on, let's move on.

.htaccess in wp-includes

Block direct access to PHP files

Create a .htaccess file in wp-includes and paste the following code into it to prevent PHP files from being loaded directly:

# Block les accès directs aux fichiers PHP (Merci à Sucuri)
<Files wp-tinymce.php>
allow Aallow from all
</Files>
<FilesMatch "\.(?i:php)$">
  <IfModule !mod_authz_core.c>
      Order allow,deny
     Deny from all
   </IfModule>
  <IfModule mod_authz_core.c>
      Require all denied
   </IfModule>
:</FilesMatch>
<Files wp-tinymce.php>
  Allow from all
</Files>

<Files ms-files.php>
  Allow from all
</Files>

The code above is provided by the Sucuri plugin.

.htaccess in wp-content

Block direct access to PHP files

For the wp-content folder, the code is similar, minus the exceptions:

# Block les accès directs aux fichiers PHP (Merci à Sucuri)
<FilesMatch "\.(?i:php)$">
   <IfModule !mod_authz_core.c>
     Order allow,deny
       Deny from all
  </IfModule>
   <IfMod_authz_core.c>
      Require all denied
   </IfModule>
:</FilesMatch>

.htaccess in wp-content/uploads

Block direct access to PHP files

Also with this code, protect the folder where the media are stored to prevent PHP files from being executed by someone else (a bad hacker for example).

# Block les accès directs aux fichiers PHP (Merci à Sucuri)
<FilesMatch "\.(?i:php)$">
   <IfModule !mod_authz_core.c>
     Order allow,deny
       Deny from all
  </IfModule>
   <IfMod_authz_core.c>
      Require all denied
   </IfModule>
:</FilesMatch>

Conclusion and resources to go further

Although a lot has been covered in this article, it is possible to go further in the configuration of your.htaccess file.

These include the WordPress Codex, Apache documentation (the software that runs your server) or the Perishable Press blog (they even wrote a book about it).

I would like to remind you to make your changes with the utmost care. Errors or incompatibilities can occur depending on the web hosting provider you are using on your site.

Always keep a backup of the original.htaccess file to restore it in case of a problem.

Well, that was quite a post, wasn't it?

Thank you for reading it until the end 🙂

And if you are used to using.htaccess files on your websites, share your snippets in the comments below.