jim.shamlin.com

Stupid htaccess tricks

An htpasswd file can be placed in any directory of a Web server to perform a myriad of useful and stupid tricks.

One caveat: Some ISPs don't allow this, as htaccess files can be misused or abused to do some things that can harm the stability or security of a server and they'd rather not deal with the consequences.


Basics

An htaccess file (named .htaccess, with a leading period) enables you to specify Apache server directives that will take effect on any request made of that directory, or any subdirectory it contains.

Worth nothing that if there's anything you want to do server-wide, you can and should set them up in the server's main configuration file (httpd.conf) instead, but if you want to do something unusual in just one location, or if your server is multi-homed and you only want to impact one site, an htaccess file may be a better alternative.

It is entirely possible to set directory-specific commands in the server config file, but I don't recommend it. Hacking the config file is dangerous, and a simple mistake can do widespread damage, so I try to avoid it whenever possible. Even if you're configuring an empty server, you might change your mind later, and will have to face that risk if you make these customizations to the config.


Serving Custom Error Documents

Most Web servers will return default messages when an error occurs. These messages may be brusque, cryptic, unhelpful, or may disclose information you'd rather keep private (such as the e-mail address of the server administrator).

Fortunately, you can hack the htaccess file to return a custom error message, thus:

ErrorDocument 401 /errors/authreqd.html
ErrorDocument 403 /errors/goaway.html
ErrorDocument 404 /errors/notfound.html
ErrorDocument 500 /errors/scriptbarf.html

You can set a specific message for any error type (I've pulled together a list).

The document specified is usually an HTML document on the same server, with a path specified from the document root. You can also send users to a different server by providing a full URL, or direct them to a different file type (such as a CGI script that will detect what they were trying to do).

You can even specify HTML code to display:

ErrorDocument 404 <HTML><HEAD><TITLE>Not Found</TITLE></HEAD><BODY> [etc.]

Password Protection

An htaccess file can be used to password-protect a directory, but I've documented that elsewhere and won't get into it here.


Preventing or Restricting Directory Listing

If there is no default document in a directory, most servers are rigged to return a list of all files in that directory. You may want to prevent this, generally to discourage bandwidth thieves. There are a couple ways to do that.

The first option is to turn off the index entirely, such that the server will display a "directory listing denied" message (or throw the user to a custom error document for a type 403 error).

Options -Indexes

An alterante method is to allow the index to render, but not show any file contents:

IndexIgnore *

You can use IndexIgnore to hide only certain files and file types. For example, if you wanted to hide all gif and jpg images and a page called "hideme,html", you can do this:

IndexIgnore *.gif *.jpg hideme.html

That will enable the directory to display all files except those ending with a 'gif' or 'jpg' extension and the 'hideme.html' file.

And finally, if directory listing is disabled by default and you want to turn it on for a specific directory, do this:

Options +Indexes

Blocking by IP Address

If you want to keep users out of a given directory and can figure out their IP address, or allow only users from a certain IP to enter, you can use this:

AuthType Basic 
Satisfy Any ΚΚΚΚΚ
<Limit GET POST>
order deny,allow
deny from 123.999.128.929
allow from all
</Limit>

This will allow anyone except the IP address specified to access files in the directory. There's a lot of flexibility:

There are other combinations and nifty tricks, I'm sure, but this covers most of what I've needed.


Blocking Files

Rather than blocking access to the entire directory, you may wish to block access to certain files only.

<Files datafile.dat>
order allow,deny
deny from all
</Files>

In general, I'd prefer to place the file in a directory outside the document root for better security, but in some instances, the data may have a low level of sensitivity and you'd want to keep it in the same directory as other files that use it, for convenient maintenance.


Blocking by Other Factors

Using the rewrite engine can enable you to block by other factors:

RewriteEngine On 
RewriteCond %{HTTP_USER_AGENT} ^EvilSpider [OR] 
RewriteCond %{HTTP_REFERER} ^evilsite\.com
RewriteRule .* - [F]

Each RewriteCond specifies an HTTP header to check and a value to match against in order to activate the specified rule. And to be honest, I've not delved into it enough to explain the options for the RewriteRule - what's shown above works for me. Perhaps I will get more curious later.


Changing the Default Page

The Web server is designed to serve a default page if no file name is specified buy the user (generally index.html), but you can change that:

DirectoryIndex specialfile.php

You can even specify a number of options, separated by spaces, and the server will attempt each, from left to right, though I've seldom needed to do that (generally, if you're overriding, you know what file you want to use instead), except in cases where there were subdirectories and I wanted to revert to the usual index within them.


Enable Specific MIME Types and Handlers

If there are one or more file types you want to enable in a specific directory, do this:

AddType application/x-shockwave-flash swf
AddType text/html .shtml
AddHandler server-parsed .shtml

Admittedly, this is rare - it's generally best to do this in the server config file to enable those MIME types in any directory, though there have been a few instances in which I've felt the need to do this, such as when I've set up a share for someone else and they want/need to do something I generally avoid (like server-parsed HTML files).


Redirecting

You can redirect requests for a file to a different one, thus:

Redirect /oldpath/file.html /newpath/file.html
Redirect /anotehroldpath/ /anothernewpath/

I don't recommend using this in most instances. It's better to put up a page indicating the move so that people will update links and bookmarks, or else they will have the impression that the resource exists in its old location and continue to use the old links/bookmarks and tell others the old address.