Using .htaccess Effectively

 

This guide is designed to be a fast and informative guide to using .htaccess effectively. Before we can dive into what you can use the file for, it is important to understand why the file exists and where these commands are going.

Apache is designed to be a robust web engine with both flexibility and security. How Apache is configured is a topic for anotherday. For the purposes of this article, understand that if the option is set, Apache will import and apply custom settings from .htaccess. This allows users or administrators to dynamically update Apache settings as needed.

How to create a .htaccess file

In most configs, .htaccess is loaded from the directory you want settings to be applied in. And in most configs, the settings placed in your .htaccess will be applied three directories deep.

 webuser@hostname [/home/webuser/public_html]# ls -al .htaccess
 -rw-r--r-- 1 webuser webuser 960 Jan 31 07:39 .htaccess

The file itself will need to be readable to your web process in order for it to be loaded.

Restricting access to a file

One of the common uses of .htaccess is to prevent outside users from gaining access to files stored in your web accessible directory. For example, if you have a custom php.ini file, this is not something you want to give outside users access to. You do however need to give your web process access to read the file. If your web process can read the file, so can users visiting the page if they know the file exists. You can block access using the following directives:

 <file php.ini>
  order allow,deny
  allow from 10.10.10.10
  deny from all
 </file>

This will tell Apache you want to allow access to users first, then deny from anyone who is not allowed. You will allow from IP 10.10.10.10 and then you will deny from everyone else. There are also other fun ways to block access to a file.

This directive will block public access to all files in a directory but will allow server side processes to open the files.

RewriteEngine on
RewriteBase /
RewriteCond %{THE_REQUEST} ^.+$ [NC]
RewriteRule .* - [F,L]

There are a lot of fun ways to restrict access through .htaccess. Further in this article, you will find how to password protect files and folders.

Creating custom error files

You can create your own Error page based on the header code returned for the request. This is great for error handling.

 ErrorDocument 400 /bad_request.php           ( Generic error caused by malformed user input )
 ErrorDocument 401 /auth_required.php         ( Authorization is required to access realm )
 ErrorDocument 403 /forbidden.php             ( Web process does not have permission to access file )
 ErrorDocument 404 /file_not_found.php        ( File is not found )
 ErrorDocument 410 /file_gone.php             ( File is no longer available )
 ErrorDocument 500 /internal_server_error.php ( Commonly caused by scripting errors )

You can even take these custom error files a step further and redirect to a single error script and load custom includes.

 ErrorDocument 400 /fail.php?err=400

Something worth mentioning about the error documents. M$ Explorer will not download generic error pages and instead suplament its own page if it detects the error page is generic. While the process is not really understood, one common element that is the error document page size is less than 512kb. You can find more information regarding this at Q294807

Static file redirection

Redirecting can be necessary for updating search engines and users of a new file location. When you move a file to a new location, or change how your site links its files, you risk users having out of date bookmarks and search engines no longer listing your pages. Redirecting based on conditions is simple using the Redirect statement. It is worth noting that redirecting in this fashion will change the URL in the users browser to the new location, it is not a transparent redirect.

Redirect 301 /old_location.htm http://www.webhost.com/new_location.htm

The redirect directive will allow you to redirect for status codes of 300-400.

Password Locking a Directory

Sometimes you need to protect access to directories from everyone but a few people. Password protecting them is the quickest and easiest way to accomplish this. To facilitate a password/authentication system, Apache allows the user to pass directives through mod_auth, mod_digest (depreciated), mod_auth_digest, and mod_auth_mysql. Each of these modules contains directives to allowing the user to pass requests to protect directories through the .htaccess file.

There are three types of authentication you can use. Auth basic, Auth digest, and Auth Mysql. All three allow you to protect realms containing data, each has its own level of complexity and functionality. As you can guess, Auth Basic is the most basic and easiest to use form of authentication.

Basic Authentication allows the administrator to restrict access to certain members using a flat file stored in plain text. Filesystem security is a whole other topic for another post, just understand that using flat files in plain text is not a very secure way to protect your data. But this method will get the job done by prompting the user for a password on the site. The following two examples use mod_auth.

AuthUserFile /home/webuser/.htpasswd/htpasswd-folder
AuthType Basic
AuthName "Protected Folder"
require valid-user

You will notice 4 key entries for this function. First off, the directory this file is contained will now prompt the user to authenticate. The AuthUserFile is the full path in the filesystem to the htpasswd file which holds the user table. The AuthType tells Apache what kind of authentication to look for. AuthName identifies the area for which is being secured to the user. And require valid-user tells Apache to only let people who have authenticated into the directory.

<files "ninja.rar">
 AuthUserFile /home/webuser/.htpasswd/htpasswd-folder
 AuthType Basic
 AuthName "Protected File"
 require valid-user
</files>

This is the same concept, only it restricts access to the "files" directive or ninja.rar in this case. You will use this format to restrict access to files and folders. I mentioned earlier that there are three major authentication mechanisms: mod_auth, mod_auth_digest, and mod_auth_mysql. You will use the AuthType to tell Apache which method you would like to use for authentication.

Mod Basic stores the password in a flat file using plaintext. In terms of filesystem security, this is not safe at all. If a user can browse the file system and if the permissions are set wrong on the file, any user can find out what the password is. The good news is, you can use mcrypt(). mcrypt() is a basic encryption algorithm which hides the true password from snooping users. It is however very insecure and easily crackable.

webuser@web [/home/webuser/.htpasswds]# cat passwd
webuser:32sEWajiw923

Mod Auth Digest takes this concept a step further. Mod Auth Digest will allow you to create md5 hashes for your password. Mod Auth Digest introduces a new concept called a Realm. A realm is an area or areas of a website for which users have access to. The realm in your password file _has_ to be the same as in your .htaccess file for access to work.

AuthDigestFile /home/webuser/.htpasswd/htpasswd-folder
AuthType Digest
AuthName "Protected Page"
AuthDigestDomain /Protected/ http://www.mindbend.org/Protected/
AuthDigestNonceLifetime 300
require valid-user

The AuthDigestFile is your password file. This time it uses MD5 hashes instead of mcrypt(). The AuthType will be set to Digest. The AuthName is your "realm" for the protected area. The AuthDigestDomain is special. This directive is mandatory and must contain at least the root URI(s) for this space. AuthDigestNonceLifetime 300 is also special. This defines the time period for the server to check if the nonce period is active. This is the lifetime of the authentication performed. This number is measured in seconds and provides a non expiring nonce at 0. And of course, you must require the user to authenticate to get past.

webuser:Protected Page:23j39i92323iijnm23njadnj39ifadik

Auth MySQL is a very powerful system of authentication which uses Apache to query a specified MySQL database to perform the authentication. If you understand what this means, documentation is not really necessary. If you do not understand what this means, there are far more detailed documents on the internet discussing how this works and how to set it up. I am only mentioning it as I feel it is too powerful of an option to leave out.

AuthType Basic
AuthName "Protected File"

Auth_MYSQLhost localhost
Auth_MYSQLusername webuser_modauth
Auth_MYSQLpassword jk23#@usfi8s
Auth_MYSQLdatabase webuser_modauth
Auth_MYSQLpwd_table modauth_folders
Auth_MYSQLuid_field modauth_user
Auth_MYSQLpwd_field modauth_pass
Auth_MYSQL_EncryptedPasswords on
require valid-user

The concept is pretty self explanatory if you have ever setup a database. While this is a very interesting way of locking down a directory, it should be noted that this module has security flaws in its methodology and you should use this method sparingly.

More to come with time!

 

The artist brings something into the world that didn't exist before,
and he does it without destroying something else.
-- John Updike, writer (1932- )