Today we will go over some practical uses of htaccess files that you can use in your web applications.
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.
There are ways to fix this growing problem using htaccess. First here is the image we are trying to protect.

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.
- First we need to turn on the rewrite engine in Apache, this allows us to redirect the user's request.
- 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.
- 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.
- 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.
#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.
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.

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.
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.

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!
- Follow us on Twitter, or subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.
Related Posts
Check out some more great tutorials and articles that you might like
Plus Members
Source Files, Bonus Tutorials and
More for $9 a month for all TUTS+
sites in one subscription.










User Comments
( ADD YOURS )Filip Benes July 17th
Thanks! Useful, but could you write another article about mod_rewrite
( )I and I think many others would really appreciate it!
Eric July 17th
Flip,
Check out the regular expressions tuts on http://blog.themeforest.net, and then take a look at the O’reilly book Apache Security
mod_rewrite is hell to understand if you don’t have a solid understanding of mod_rewrite.
( )Eric July 17th
regular expressions I mean. ; )
Patrick Sweeney July 17th
I agree, a mod_rewrite tutorial would be good as well.
( )Meshach July 17th
Another vote for mod_rewrite
crysfel July 17th
awesome!! this is really good!! i didn’t know about the “upgrade” redirect.
thanks you so much!!
( )Cvitano July 17th
Nice list of .htaccess features, but I miss the url rewriting methode. I know it can also be done with .htacces.
( )There are not many tutsites that cover the basic of a good structured website. Where a domain with .com/about/ will be redirected to the according about.php page and still show /about/ in the title bar.
Eric M. July 17th
Very useful.
( )Eric July 17th
Thanks for the info. Being more of a sysadmin than developer I always appreciate these kinds of tuts.
( )Paul Davis July 17th
Good tutorial, I really should add a few of these to my sites!
I would also like a tutorial on mod_rewrite as well!
( )Duncan July 17th
Awesome list, this gave me many ideas of what to do with htaccess other than just the cleaning up of dynamic urls.
( )HMM July 17th
Expecting a mod_rewrite tutorial .This is also great !
( )NickyB July 17th
Excellent article.. always nice to see how much you can do with the htaccess file which reminds me..
( )/me runs off
Daniel Wood July 17th
Guess this tutorial was chosen over mine -_-
I had a 3 part series planned; basic, intermediate, advanced. I was going to cover mod-rewrite extensively as well.
Oh well
( )Mike July 17th
None of these are new to me, but the clear and concise explanations have definitely expanded my knowledge.
A mod-rewrite and pretty urls tutorial would get my vote too.
( )Ken July 17th
Please tell me that email shown in #1 is fake.
( )‘I am an honest business man…’ NOT.
People like that should be punched repeatedly in the head.
Lamin Barrow July 17th
Heheh.. i thought that was hilarious too.
( )Michael July 17th
Haha…nice. I agree though. It’s just amazing what people can complain about, try to sue, and actually get money for. Oh well…
Great tut though!
( )Giovanni July 17th
I needed to know some of these solutions, thanks!
( )Brian Temecula July 17th
Redirect while performing upgrades is very useful. I don’t see that one a lot in other .htaccess tutorials. I actually do it through php so that the upgrade message is styled, but I guess sometimes it wouldn’t be possible.
( )Octavio Corral July 17th
Is that e-mail from the hot linker real? O_O haha I cant believe that
( )Noah Hendrix July 17th
To all asking the email is one that circulated the internet a few weeks back and does not belong to me, more info from the recipient is found on his blog:
http://www.shapelessmass.com/index.html/?p=578
( )Ken July 17th
Oh.
My.
God.
I simply cannot believe this isn’t made up.
He was a better man than me. I would have returned the images back to the site but the new images would be MUCH different…if you know what I mean.
Aayush July 17th
I never quite get comfortable with htaccess….This helped….
( )Idowebdesign July 17th
Nice article, really useful !
( )Max Stanworth July 17th
yup how to re-write urls that have php variables would be helpful too!
will the hotlinking code block images in feed readers?
( )Noah Hendrix July 17th
Hmm good question not really sure. If they cache the image then no, but if they are pulling live from the server I guess it probably would. One idea to circumvent that would be if they use an iframe I suppose.
( )Noah Hendrix July 17th
It appears everyone is clamoring to see an htaccess tutorial using mod_rewrite, I have put that on my list of subjects to cover any specifics you’d like to see be sure to put them here, or @noahhendrx on twitter.
( )Brian Temecula July 17th
mod_rewrite can be hard to grasp without some regex experience. When I was learning mod_rewrite, the best tutorial I found was at phpfreaks.com. Unfortunately, they redesigned their site (after being hacked I believe), and I can’t find it to share with ya’ll.
( )Daniel Groves July 17th
(!) Ideas! =D
( )Brandon July 17th
I always run into this issue, someone has a site, they want an update with a CMS, so I install TXP or Wordpress (along with their htaccess files, and their setup of mod_rewrite for pretty urls)… but how do I redirect people to a temp page during the updates (as in #4) in this situation, because it ends up conflicting with the mod_rewrite setup for the CMS?
( )Robbert July 17th
Thank you for your information
Especially no. 4 is useful for me
( )xirclebox July 17th
The fact that the “honest business man” was leaching images to build his business and had the nerve to threaten to call his lawyer. Comedy!
Good info here. Thanks for the post.
( )Fynn July 17th
Nice article! And that email really made my laugh..
But I also would like to see a indepth article about mod_rewrite..
Some specific ideas:
changing url’s in this way:
normal url: http://www.mysite.com?var1=majorsubject?var2=secondsubject turning into var1.mysite/var2
Is that possible? To also use (fictive) subdomains in mod_rewrite?
( )Filip Benes July 17th
Yeah! I would like to see something like this
( )Nicholas Z. Cardot July 17th
I laughed so hard when I read those hotlinking emails. Those are hilarious. Thanks for these tips.
( )Dennis July 17th
Great article…. I have to say I was quite literally laughing out loud reading his email about how he is such an honorable business man… and the mention of a lawyer? priceless!
( )lrntlbx July 17th
GReat ! So simple, so excellent ! Woaaa !
( )Ben July 17th
Oh excellent post! Thank you very much! haha I especially liked the email from the one on hotlinking
( )Smartarse July 17th
For performing upgrades the best solution is to have the holding page return a 503
( )Zach Dunn July 17th
This is really useful, I wish I had this article about a week ago with the IP bans. Great writeup Noah!
( )Gabriel Amorim July 17th
really nice… thank you
( )Robert July 17th
Good little collection. I’d definitely add the 301 redirect when you want to say switch a site from an old to a new URL structure nad preserve your search engine rankings as much as possible:
Redirect 301 /old/old.html http://www.domain.com/new.html
( )Synapse Syndrome July 17th
Another great use for .htaccess, of that can use it to keep URLs meaningful and consistant, even when you change technologies, like from .aspx to .php.
This is what the inventor of the web has to say about that: http://www.w3.org/Provider/Style/URI
Also, you can use .htaccess to treat .html files and .shtml, so you do not have to include that weird file extension when you want to use Server Side Includes (which are really cool, otherwise).
( )Synapse Syndrome July 17th
Another good use for .htaccess is to keep meaningful and consistent URLs, even when you rename files or change technologies (like .asp to .php). This is what the inventor of the web has to say about that:
http://www.w3.org/Provider/Style/URI
.htaccess is also really useful to make .html files treated like .shtml, so you can use Server Side Includes (which are great) without having to use that weird file extension.
( )ben chen July 17th
thanks ,but in asp how could setting htacess
( )Seich July 17th
Really nice tips.
( )KC July 18th
Love that email. It’s gold.. your article too, of course, but not in the same sense
thanks!
( )prakash July 18th
hi this tutorial is good
( )webn July 18th
Excellent Hendrix. Very helpful for professionals.
( )Tomas July 18th
Nice article, especially for beginners.
I also used .htaccess in a funny way. I wanted to experiment with User-Agent filtering… Especially with Web Crawlers, spiders and Bots. So I blocked all “human” visitors on a live website, and allowed only web crawlers to access the site. If you interested in the result look on my blog post:
http://www.dobrotka.sk/blog/use-htaccess-to-filter-visitors-and-crawlers-based-on-user-agent/
( )Patrick July 18th
Ahm, okay…
Well, did you have turned off your referer variable in your browser? Than you’ll see, that your number 1 isn’t as good as you thought.
There are several Plugins, Firewalls and so on, that kills the referer string of a httprequest. And without it users can see every picture.
Think a php based solution is much better.
( )Some name July 18th
Most ways of implementing an anti hotlink system (be it .htaccess, php, asp, whatever) uses the the http referrer header. I don’t think there is any clean way to do it. I think the best solution would be an automated (cron job or something) or manual system that simply checks the logs if there’s a specific domain (checking the referrer field) that has taken a lot of bandwidth, and add those domains to a blacklist as that wont f*ck anything up for normal users.
( )Patrick July 18th
I know a really secure solution for it, trust me
the biggest goal: i don’t need the referer. IP, Browser, Timestamp – or just a unique key – that’s all.
Needs:
– mod_rewrite (optional)
– php
– some userdata (IP, browser, timestamp of visit…) or unique key to build md5 string
– a bit coding skill
the idea:
build an unique URL to the file for each user who accesses the file, p.e.: domain.com/img/74mnd36z54mf/folder/filename.png or without mod_rewrite: domain.com/file.php?/img/74mnd36z54mf/folder/filename.png
Important: the real path to the image is _not_ img/folder/filename.png or img/74mnd36z54mf/folder/filename.png, that will be too easy to find out. Use a totally other name for the base image folder. And also impotant: Don’t use indexing on the webserver.
74mnd36z54mf = sample unique key to identifier user.
There are two ways to finally restrict the access to one unique user: store the unique key in a $_SESSION (cookiebased or urlbased) or store it in a database. Bind this unique key with the ip address of the visitor. Optional you can set a time limit for accessing. Bingo: Only this unique user will get now the right image.
Well, okay, true: users can deeplink the images again. But: the unique key is bind to this user, only he can see the right image and he’ll think all is ok. All other users will see a warning, advertising like “Hey guy, this image was deeplinked by the sites administrator, you can get the right image on http://www.domain.com” or whatever. this warning can be set up with an non-expiring header, so that the traffic will be small. Free ads, isn’t that cool?
I have tested this idea with a simple non-dynamic script (one image only, linked within the php file), it works really perfect. It’s only a lot more complicated, when you want to use it dynamic like a databased gallery, newsscript or whatever.
Some name July 19th
That’s a pretty good solution but theres a small down, for a site with a big userbase the session managing will increase the server load quite a bit. Other than that it’s quite good, but also extremely easy to circumvent.
Patrick July 19th
No, its not as easy to circumvent as you think. If you don’t know the real path to the images, you will never be able to circumvent this solution. Every user has a unique ip (okay, there are proxys, right… but this can be ignored). generate a unique key, use it directly in the url, bind the key to the user – no way to circumvent it.
But in one thing you’ll be right: This solution CAN(!) increase server load. I explicitly said: You need a little bit coding skill – than you’ll know how to work without or only small increasing server load. For example: Think about Expire-Header – you don’t have to read in all images with php on each page impression. And another: its recommended for each larger site to outsource their images on another server to keep connections and server load per user small.
Some name July 19th
All you need to circumvent this is to generate the set-cookie http header (that’s apache’s default way to store session id’s), this can be done by having an invisible iframe that simply loads the smallest page where the session is set) before loading the images, it would be maximum 10 lines of js to circumvent it… but if someone’s that dedicated to hotlink your images you should feel proud
Patrick July 19th
Right, that can be possible
But the other side of this fact is, that this is a kind of criminal activity, in germany you can demand compensation. Don’t know how this will be in other countries.
Okay in this case youre right – but what if you DON’T use PHP-Session? It’s only _one_ way to prevent hotlinking. The other way is over the IP Address of the user. generate a unique key, store it with the visitors ip in a database. right, then you have to check the userip and unique code on every request, but THAT will be really secure. This solution should be used for downloads. The way over a session is really secure enough for images.
Patrick July 20th
Hah, i’ve thought about it.
No, theres NO way to circumvent my solution – even not when sessions are used. The image-stealer uses a unique key in the linked image url on his site, so that every other user can’t view this image. A “bypass-iframe” wouldn’t have any effect of this fact, because each user get his own unique key in the image url.
Some name July 18th
Hi! Nice little list of useful .htaccess features. I’d just like to point out that the hotlinking protection might be more destructive than useful as a lot of users disables the http referrer header (HTTP_REFERER (heh funny thing the common miss spelling of referrer made it’s way into the http protocol
)) and a lot of firewalls and other applications that’s meant to keep your privacy also disables the http referrer header.
Off topic:
( )I’d like to see some SEO tutorials on here
Nokadota July 18th
Wow, can’t believe that someone really had the audacity to threaten to sue over not being able to use *someone else’s photos*. Amazing.
Anyhoo, thanks for the tut.
( )Webhostright July 18th
Thanks, this is extremely useful, i found that mesage that was received hilarious, very cheeky but very funny, it shows how ignorant some people can be at times, either that or naive possibly.
Thanks for the information regarding 4. especially.
( )Jake Rocheleau July 18th
These are some pretty useful tips, especially with Apache being such a popular and free web server platform.
( )WebHostDesignPost July 18th
Thanks for the post, I think I’ll be using the Redirect While Performing Upgrades the most.
( )Myfacefriends July 18th
i like the number 4. but how to do this if the user type http://www.mysite.com it will redirect it to http://mysite.com many thanks.
( )MGK July 18th
Hello,
thank you for these explanations
I however have one question:
Using a modalbox plugin (jquery for example) to open a page abc.html from a link on page index.html, I would like to know if we can use htaccess to prevent any user to open page abc.html if its not through the modalbox of page index.html ?
like maybe something as allow 127.0.0.1 deny all ?
i don’t even know if that’s possible.
or maybe its in php, like with a define(”,”) but since its not an include…
any advises ?
thank again !
( )MGK July 18th
and also, whats the difference between
IndexIgnore *
and
Options -Indexes
?
( )MGK July 18th
forget it, I just figured it out…
IndexIgnore * won’t redirect to an error, but won’t display anything
whereas
Options – Indexes will redirect to an error
(which is quite usefull to make it look as an error for scriptkiddies)
( )Samuel July 25th
There is another difference:
On some shared hostings the use of “Options” Apache directive is forbidden.
But on those restrictive hostings IndexIgnore is allowed.
Jan July 19th
Great tut. but what I’m missing here is the .htpasswd protection
( )Jeff Starr July 20th
I recently put together a smorgasbord of delicious password-protection tricks:
http://perishablepress.com/press/2009/07/13/htaccess-password-protection-tricks/
Hopefully it will help
( )Carl - Web Courses Bangkok Instructor July 19th
Really useful thanks! So the email you received was that to you or a friend, what was the outcome?
( )Dave Kennedy July 19th
htaccess IP blocking…. Yes it’s ok for a few IPs but seriously not a good idea if you have a long list of IPs which will no doubt be the case, the .htaccess is served before every page load, to both whitelist and blacklist IPs. Long lists lead to long waits.
Addressing most of the comments here as well, using htaccess for seo-pretty urls prob isnt a good solution either, it works but is it maintainable as a site scales? You get so much of this out the box with frameworks that use MVC which in my opinion is a more elegant solution… see the CI screencasts on here for info on that.
I stopped worrying about hotlinking ages ago and dont think it’s a big enough issue to address, there are legitimate uses for hotlinks such as affiliate schemes or people linking to your site and want an image to link with.
Error docs, well use MVC again and you can have more meaningful error pages, and finally directory listings… you should have been doing that already anyway!!
( )david July 19th
Get ride of the www in a domain:
RewriteEngine On
( )RewriteCond %{HTTP_HOST} ^www\.ramaboo\.com$ [NC]
RewriteRule ^(.*)$ http://ramaboo.com$1 [R=301,L]
Ramon July 20th
Well, that’s too common info, IMHO. This can be found anywhere.
( )Martyn Web July 20th
I find this useful, Ive only really used the htaccess for redirecting away from the index.php and forcing a www. prefix. Oh, and to provide a custom 404 but thats about it.
Its good to know that these options are available but I probably wouldn’t bother with these on smaller sites.
( )André July 20th
Another great use of .htaccess you can protect a file or folder by password, also you can use a password file or also you can redirect for PHP manage the file as you want.
And another great use for this, is to create those blog like links, when you hit the archive button shows like http://www.myaddress.com/articles/2009/07 and this shows all the list of articles of july in year 2009… or just http://www.myaddress.com/showarticle/10 where 10 is the ID of the artcile in the database, showarticle can be just a showarticle.php file for example
( )Troy July 20th
Ha! Only a programmer would call an htAccess tutorial “fun”
( )(btw, they are fun.)
Christine July 20th
Thanks for that- I’d forgotten to do the hotlinking thing.
(b.t.w- for some reason I couldn’t see the Name, Email and URL text in the comments fields here in my Opera browser)
( )DemoGeek July 21st
Blocking the user by IP address would come in real handy for me (and for many others as well). That way we can ban the user who is clicking on the AdSense ads 400 times and getting people to lose their sleep. It might be a constant effort but could be done and could give us some shield than those dreaded AdSense emails. Make sense?
( )roy July 21st
Great Tutorial,It’s very useful…Thanks!
( )Prabin July 21st
if you post article about mode_rewrite then that will be great. Thanks for the article..
( )hyoori July 22nd
Thank you very much!!
( )Tomi July 22nd
Thanks!! Great article!
( )James Solomon July 23rd
Good tut, but if you wanna see some real crazy Apache tricks, this guys blog is great, http://www.askapache.com
( )mary August 10th
If it’s a bright, clear day outside, you may instinctively reach for your sunglasses when you head for the door.. But you probably do think about sunglasses when you go to buy a new pair — whether you walk into the discount store or the Sunglass Hut at the mall, you are immediately struck by the bewildering array of choices before you! The style of the frame and size of the lenses also make a difference. Is that $200 pair of Serengeti sunglasses really any better than a $10 pair from the flea market?
( )S.A.T August 19th
Good tut, very complete, and precise.
Thanks!
( )I like it
wholesale lingerie October 2nd
almost every day i need to read your Article. so good. Thanks for sharing those valuable information .
( )alfred October 3rd
I am a newbbie. May I ask one stupid question. Where should the .htacess file should put in to prevent the hotlinking of the images. should be on the same level with the image folder, Am I right?
( )If the Image folder we redirected by another .htacess to another level, Then this file where I should put?
Joe October 11th
I like this tutorial a lot.
( )Gangster92 October 22nd
We had four videographers present. ,
( )www.leadjewellry.com November 15th
ugg
( )ugg boots
ugg boots sale
uggs on sale