Thursday, July 23, 2009

5 Fun and Practical Htaccess Solutions

Requirements

Htaccess files are plain-text configuration files used by the Apache HTTP web server. They allow users to set directory level options without requiring access to the httpd.conf file. As such it is required that your server uses Apache, and a web host that allows htaccess files (the most popular hosts do).

I assume a basic working knowledge of htaccess, but if you need to freshen up check out this article by Joseph Pecoraro

1. Prevent Hotlinking

Hotlinking, or inline linking, is when one web site links directly to an object on another site. This costs the hosting site bandwidth to provide the image on the page of the second site. On popular photo sites this can be a major problem, albeit humorous at times.

ShapelessMass.com

http://www.shapelessmass.com

There are ways to fix this growing problem using htaccess. First here is the image we are trying to protect.

view plaincopy to clipboardprint?

  1. RewriteEngine on 
  2. RewriteCond %{HTTP_REFERER} !^$ 
  3. #domains that can link to images 
  4. #add as many as you want 
  5.   RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?demo.collegeaintcheap.com [NC]
  6.   # RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?noahhendrix.com [NC]
  7. #show no image when hotlinked 
  8.   RewriteRule \.(jpg|png|gif)$ - [NC,F,L] 
  RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$

#domains that can link to images
#add as many as you want
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?demo.collegeaintcheap.com [NC]
# RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?noahhendrix.com [NC]


#show no image when hotlinked
RewriteRule \.(jpg|png|gif)$ - [NC,F,L]


We will step through this line-by-line.




  1. First we need to turn on the rewrite engine in Apache, this allows us to redirect the user's request.


  2. Next we start setting our conditions using RewriteCond. This is a function that takes two arguments: TestString and CondPattern. TestString is the string we want to check our CondPattern against (using regular expressions). ${HTTP_REFERER} is a variable provided by Apache that holds the domain the request came from, in this instance we want to allow requests from blank HTTP referrers to protect users who are on a proxy server that sends blank referrers.


  3. Next we set the domains from which we will allow our images to be linked using the same syntax except now we provide a URL. The [NC] flag at the end of the command simply instructs the engine to ignore casing. You can add as many lines domains as you'd like here, using the same syntax. For the sake of example I added my personal domain, but commented it out.


  4. Finally, the last line is the RewriteRule we wish to use if any of the conditions above are not met. It takes two arguments as well Pattern and Substitution, where pattern is a regular expression match and substitution is what we want to replace any matches with. In this case we are looking for requests that end in jpg, png, and gif; if found we want to use a blank substitution. However in the flags we tell it furthermore what we want to be done, NC means no case, F sends a 403 forbidden error to user, and L tells the engine to stop rewriting so no other rules are applied.



This is fairly straightforward, but perhaps we are interested in telling the user we don't want them to hotlink our images, so let's redirect all hotlinked requests to an image instead of sending a 403 forbidden error. This is done by replacing the last line with this code.



view plaincopy to clipboardprint?




  1. #show an alternate image 


  2.   RewriteRule \.(jpg|png|gif)$ http://demo.collegeaintcheap.com/envato/htaccess/hotlink/images/hotlink.jpeg [NC,R,L]



  #show an alternate image
RewriteRule \.(jpg|png|gif)$ http://demo.collegeaintcheap.com/envato/htaccess/hotlink/images/hotlink.jpeg [NC,R,L]


You can change url to any image path you'd like on your domain, but remember it needs to not end in jpg, png, or gif as it will reapply the rule and send the server into a never-ending loop. I chose to use the older .jpeg extension to fix this. The R flag that replaced F simply sends a redirect.





2. Block User By IP Address


This is a great little tip if you have a spammer on your website. If you can find their IP in your logs, simply add it to an htaccess file.




  1. Order Deny,Allow 


  2. Deny from 24.121.202.23 


  3. # Deny from 0.0.0.0 



  Order Deny,Allow
Deny from 24.121.202.23
# Deny from 0.0.0.0


Using the Order directive in the mod_access module we can specify IPs to deny and allow. Simply using the syntax Deny from IP ADDRESS we can forbid those users from accessing our directory.





3. Error Documents


All production ready sites should use custom error pages for a professional touch. This is easy using the ErrorDocument directive in Apache's core. A custom page is far better than the default Apache error pages.





view plaincopy to clipboardprint?




  1. ErrorDocument 404 http://demo.collegeaintcheap.com/envato/htaccess/errors/404.html


  2. ErrorDocument 403 http://demo.collegeaintcheap.com/envato/htaccess/errors/403.html


  3. ErrorDocument 500 http://demo.collegeaintcheap.com/envato/htaccess/errors/500.html



  ErrorDocument 404 http://demo.collegeaintcheap.com/envato/htaccess/errors/404.html
ErrorDocument 403 http://demo.collegeaintcheap.com/envato/htaccess/errors/403.html
ErrorDocument 500 http://demo.collegeaintcheap.com/envato/htaccess/errors/500.html


ErrorDocument takes two arguments error-code and document. In the code above I created error documents for the 3 most common HTTP errors: 404 not found, 403 forbidden, and 500 server error. Then you can provide the full URL or relative path to your error documents. You could also them redirect to a PHP script that logs the errors in a database or emails them to you (might get annoying though). This is a great way to take control of errors in your web application, be sure to check out Smashing Magazine's 404 error page showcase for inspiration.





4. Redirect While Performing Upgrades


If you are performing a major site upgrade you most likely should redirect users to a page informing them. This prevents users from seeing broken pages or potential security holes while the application is uploading. One caveat to consider is that we want to allow certain IP addresses into the site for testing before it goes live all of this can be achieved in an htaccess file.



view plaincopy to clipboardprint?




  1. RewriteEngine on 


  2. RewriteCond %{REQUEST_URI} !/upgrade.html$ 


  3. RewriteCond %{REMOTE_HOST} !^24\.121\.202\.30 


  4. RewriteRule $ http://demo.collegeaintcheap.com/envato/htaccess/upgrade/upgrade.html [R=302,L]



  RewriteEngine on
RewriteCond %{REQUEST_URI} !/upgrade.html$
RewriteCond %{REMOTE_HOST} !^24\.121\.202\.30
RewriteRule $ http://demo.collegeaintcheap.com/envato/htaccess/upgrade/upgrade.html [R=302,L]


We are using the rewrite engine again to do this, but in a kind of reverse way. First we need to set a condition that excludes the document describing the upgrade otherwise our server start a never ending loop. Next we exclude a single IP address from being redirected for testing purposes. Finally we use the rewrite rule to send users to an upgrade page. The flags we have looked at before, except this time we setting the redirect to a 302 status code, telling the browser that the page has temporarily moved and to handle caching accordingly. Smashing Magazine, again, has a great showcase of Effective Maintenance Pages.





5. Hiding Directory Listing


For numerous security reasons it is a good idea to restrict directory listing, the default behavior in Apache. This can be done with a simple line in our htaccess file we can prevent visitors from seeing our directory listings.






  1. Options -Indexes 



  Options -Indexes


Now users who request a directory that doesn't have an index file it will show them a 403 forbidden error page.





Conclusion


These are several of my favorite uses of htaccess. Leave yours in the comments! I am available for help in the comments or on twitter. If there is a great deal of interest, I will do more htaccess tutorials with solutions to your requests in the comments. Thanks for reading!

No comments:

Post a Comment