Common HTAccess File Hacks

November 11, 2021 in Behind the Code

In our recent article on misleading timestamps, we discussed one of the more common hacks that are seen in .htaccess file, the use of FilesMatch tags to block access to certain file extensions or to allow access to a specific list of filenames. In this article, we are going to talk about some of the other .htaccess directives that we see in malicious files and provide some examples from actual hacks.

The .htaccess File

If you are not familiar with what the .htaccess file does, here’s a brief refresher (summarized from

.htaccess files (or "distributed configuration files") provide a way to make configuration changes on a per-directory basis. A file, containing one or more configuration directives, is placed in a particular document directory, and the directives apply to that directory, and all subdirectories thereof.

What this means is that you, as a website owner, can change the behavior of files in your site on a per-directory basis just by creating a .htaccess file and setting the appropriate configuration values in it.

  • Do you want PHP files to be displayed as text instead of executed in a directory? There are directives to do that.
  • Do you want to redirect users based on the directory in the request? There are directives to do that, too.
  • Do you want to have a file other than index.html or index.php to be the default file used in a directory? Yep, there are directives for that too.

Decoding the Directives

Setting Basic Options

The first directive that you should know about in .htaccess files is the Options directive. There are many options that you can set here, most of which you will never need to touch with a properly configured hosting provider when using a CMS like WordPress or Joomla. However, if you are making your own website from scratch or have parts of it that are not provided by the CMS. Though there are some the important options you should know about, here are three important ones to be mindful of:

  • Indexes – Tells the webserver to display the directory index (a list of the directory contents) when there is no ‘index’ file available. You will want to explicitly turn off Indexes in all cases where the directory contents do not need to be visible.
  • SymLinksIfOwnerMatch or FollowSymLinks – Tells the webserver to follow a symbolic link if the owner of the link and the owner of the target are the same. For example, if you have a new mysite.php file that you just finished and want to test it as if it were the index.php file, you could create a symlink so that index.php points to mysite.php. Since you are the owner of the file and the symlink, the SymLinksIfOwnerMatch option will allow the webserver to serve the file normally.
  • ExecCGI – Tells the webserver that CGI scripts (executable scripts) are allowed to be run from the directory.

You can ensure these are on by placing a plus (+) in front of them (+SymLinksIfOwnerMatch, for example) or you can force them to be turned off by placing a hyphen or minus (-) in front (-Indexes, for example).

If you have a directory that only has HMTL files and no scripts or scripting elements in the files, a good Options directive to use is:

Options –Indexes –ExecCGI +SymLinksIfOwnerMatch

This will prevent directory listings from being displayed (so random people can’t see what valid filenames are there) and it will turn off CGI scripting, but it will allow symbolic links so you can have multiple names pointing at the same file.

As a note, there is an additional option that enables all the important options. This is the ‘All’ option. With the number and variety of options available, the ‘All’ option can be considered a security risk and should not be used.

Changing the Default File in a Directory

The next directive is the DirectoryIndex directive. This sets the name of the index file from the typical index.php or index.html to the name of the file in the directive. For example, if you have a new index page that you want to test, you can upload it as index-new.php and set you are the following directive in the .htaccess file:

DirectoryIndex index-new.php

Now, when visitors come to that directory without specifying a filename ( for example), they will receive the content from index-new.php instead of the typical index.php.

Changing How Files are Handled

The third directive is a pair that go hand in hand: AddType and AddHandler. These directives change how the webserver handles files based on the type of file and the extension of the file.

Specifically, AddType associates a file extension, such as .gif, with a media type like application/x-httpd-php (the media type for PHP scripts). AddHandler, on the other hand, associates a file extension with a “handler” configured in the webserver. This could be a media type (like text/plain), a pre-configured handler name such as cgi-script, or a random command.

Rewriting URLs

The .htaccess file can also contain rules for rewriting the URL requested by a user. Most of the time, this is done to force users back to the main page if they go to a URL that does not exist.

For example, this is the standard WordPress .htaccess file:

# BEGIN WordPress

RewriteEngine On

RewriteBase /

RewriteRule ^index\.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /index.php [L]# END WordPress

We can ignore the lines that start with a hash symbol (#) as these are comment lines.

The first directive is RewriteEngine On. This just tells the webserver that the code to rewrite URLs should be enabled.

The next line tells the webserver what it should use for relative pathnames in the rules. This means that, for example, “index.php” means “/index.php”.

The final pieces for URL redirection involve the rules and conditions.

The first rule simply says, “if the request filename matches ‘index.php’ exactly, stop processing more rules”.

The next two lines are conditional statements (RewriteCond). These are applied separately and, if all of them are true, the following RewriteRule is applied. The first RewriteCond checks to see if the requested filename is not a file (-f tests to see if it is a file and the ! Is the negation operator). The second RewriteCond checks to see if the requested filename is not a directory. As a result, if the requested filename does not exist, the request gets rewritten to send the user to the root index.php.

A less common technique is to take the request file path and rewrite it as arguments to the index.php file. This technique uses the same RewriteCond directives to check whether the file or directory exists, but the RewriteRule is quite different:

RewriteRule ^/(.*?)/(.*?)/?$ /index.php?category=$1&topic=$2 [L]

In this example, the RewriteRule is looking for requests like and rewriting them to

This makes it convenient for writing links in your site and easier for people to link to your site.

Turning Off Authentication

Two of the more uncommon, but still dangerous directives, are the Require and Satisfy directives. These work together with the Allow and Deny directives to further enhance the security of a site.

The Require directive allows you to specify additional restrictions such as forcing requests of by a particular method, requiring authentication by a particular user or group, or even a specific format of the URI.

The Satisfy directive allows you to say how many of the access controls are needed to access the resource. Satisfy has two valid options: All or Any. “Satisfy All” is the default and forces an access request to meet whatever combination of Allow, Deny, and Require directives are set for a resource. “Satisfy Any” significantly weakens the security of a directory or site as it means that meeting any single access control will allow access to the resource.

Editing With Malicious Intent

Now that we understand what some of the directives, how do attackers use the .htaccess directives maliciously?

As was noted in our article on misleading timestamps, FilesMatch is a commonly used tag used to restrict the effect of directives. In that case, the attacker was using the Order, Deny, and Allow directives to control access to files that matched a particular filename or extension. By doing so, they disable all the legitimate files in that directory and only leave their malicious scripts available.

If they do not take that route, attackers will usually turn on Indexes because most providers have that disabled by default. Additionally, they often enable FollowSymLinks and SymLinksIfOwnersMatch to try and get into other parts of a webserver, especially if they suspect that a webserver is running as root. Attackers that do this will typically try to create links to configuration files for the CMS, database, and server in a subdirectory that can be accessed via a browser to get the passwords and data in those files.

As these configuration files can be scripts, attackers will leverage the AddType and AddHandler directives to make sure that the files are displayed in the browser and not executed.

Many attackers will also upload a defacement file to show off that they were able to hack the website and use the DirectoryIndex directive to set the index page to that file, so it is served automatically when the site or directory is accessed.

Lastly, some attackers will set the Require and Satisfy directives just in case the site uses some sort of access controls in the webserver configuration. This usually takes the form of:

Require None

Satisfy Any

This does exactly what it says. It requires that a request or authentication attempt meets none of the restrictions placed on it and then it says that the access controls are satisfied by any successful access control.

Real-Life Examples

Now we can look at some real-life examples of the kinds of .htaccess files that we see on customer sites.

This first example uses the FilesMatch tags to first block all access to files ending in “.php”, “.php5”, “.suspected”, “.py”, and “.phtml”. And then it uses the FilesMatch to allow access to the index.php and system_log.php files. This is commonly used by webshell authors to block a directory and then restrict access to their shell.

<FilesMatch “.(php|php5|suspected|py|phtml)$”>

Order allow,deny

Deny from all


<FilesMatch “^(index.php|system_log.php)$”>

Order allow,deny

Allow from all


This second example turns on directory indexing and tells the webserver that symbolic links should be followed. It then goes on to tell the webserver that everything (ForceType) in the directory should be rendered as plain text instead of expecting HTML. Next, it is telling the webserver that anything with a .php or .html extension should be treated as plain text as well. Aside from treating .shtml (HTML with Server-Side Includes) as regular HTML text, the rest of the directives are forcing files to be handled as text.

Options +Indexes +FollowSymLinks

ForceType text/plain

AddType text/plain .php

AddType text/plain .html

AddType text/html .shtml

AddType txt .php

AddHandler txt .html

AddHandler txt .shtml

This final example turns on all the options except for MultiViews (which tells servers to perform wildcard searches for files before deciding if the file is missing). It also changes the index file name to the hacker’s defacement page and sets PHP files to be server-parsed text files. Additionally, the file also sets HTML files to treated as plain text. Lastly, this .htaccess file sets an authentication requirement of “None” and allows any successful authentication requirement to grant access.

Options all

DirectoryIndex Sux.html

AddType text/plain .php

AddHandler server-parsed .php

AddType text/plain .html

AddHandler txt .html

Require None

Satisfy Any


Hopefully, this article helps you understand some of the ways in which attackers use .htaccess files. Fortunately, SiteLock already has signatures to detect many of these types of .htaccess file modifications.

If your website has been hacked and you have found these kinds of modifications to .htaccess files, contact our security experts for assistance.

About The Author

Maarten Broekman has worked as a system administrator and systems engineer for over 25 years, primarily in the shared web-hosting space. One of the main concerns for web-hosting providers is being able to serve their customers’ websites as quickly and efficiently as possible. As a result, anything that detracts from performance needed to be examined closely and this is where his interest in malware and code analysis sprang from. For over a decade, finding, decoding, and removing malware (and automating that process) has been his primary focus.

Latest Articles
Follow SiteLock