Anda di halaman 1dari 44

Stupid htaccess Tricks • Perishable Press

RT @BinaryMoon: How to load files within WordPress themes http://bit.ly/chTkpi - #wordpress HIDE

Pe rishable Pre ss
¤ DIGITAL DESIGN & DIALOGUE ¤

Stupid htaccess Tricks Upgrade Your Feed Reader

by JEFF STARR on TUESDAY, JANUARY 10, 2006 – 116 Responses


Welcome to Perishable Press

W elcome to Perishable Press! This article, Stupid htaccess Tricks, covers just about every
htaccess “trick” in the book, and is easily the site’s most popular offering. In addition to
this htaccess article, you may also want to explore the rapidly expanding htaccess tag archive.
Focused on clean code and quality content,
Perishable Press is the online home of Jeff
Starr, author, artist, designer, developer,
Along with all things htaccess, Perishable Press also focuses on (X)HTML, CSS, PHP, JavaScript, and all-around swell guy. More..
security, and just about every other aspect of web design, blogging, and online success. If these
topics are of interest to you, I encourage you to subscribe to Perishable Press for a periodic dose Archives Explore Contact Switch Themes
of online enlightenment ;)

Awesome WordPress Resources


TABLE OF CONTENTS

General

1. htaccess definition

2. htaccess comments

3. important information

4. performance issues

5. regex character definitions

6. redirection header codes

Essentials

1. htaccess comments

2. enable basic rewriting Search Perishable Press Search

3. enable symbolic links

4. enable AllowOverride Standards-based Website Design TOP

5. rename the htaccess file Presentational Design CSS, Art, Print, Graphics

6. retain httpd.conf rules Behavioral Design JavaScript, jQuery, Flash

Functional Design Ajax, PHP, SQL, HTAccess


Performance
Structural Design (X)HTML, XML, RSS, MySQL

1. disable AllowOverride Multimedia Design Audio, Photography, Video

2. pass the character set

3. preserve bandwidth WordPress, Blogging & Security

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

4. disable the server signature WordPress – Plugins, Themes, & Tutorials

5. set the server timezone Blogging Tips – Social Media & Social Networking

6. set admin email address Site Security – Anti-spam, Blacklists & Firewalls

7. enable file caching

8. set default language & character set Recent Articles


9. declare specific/additional MIME types
...loading...
10. send headers without meta tags
Get more!
11. limit request methods to GET/PUT

12. process files according to request method

13. execute various file types via CGI script Current Dialogue
Adam: HI i am, using your 2010 user agent blacklist
Security at the moment and i wanted to know if i can paste
the directive from this site under yo...

1. prevent access to htaccess Nigel@ seOtIpS: In response to the last posting, I


agree that the Internet is a great source of
2. prevent access to any file
information. However, there is great value in knowi...
3. prevent acess to multiple file types
Edward Beckett - Florida SEO: I've had scrapers steal
4. prevent unauthorized directory browsing my content on several occasions. My final solution
was to simply report them to Google ... It worked »
5. change the default index page
Th...
6. disguise script extensions
Therese: THANK YOU FOR THE CODE! I got some
7. limit access to the LAN problems with spam from a specific IP. You helpt me
a lot! Thanx again!...
8. secure directories by IP or domain
Jeff Starr: Hi Jennifer, Yes very true, there are many
9. deny/allow domain access for IP range
ways to fashion your Apache directives, but this
10. deny/allow multiple IP addresses on one line article treats the eight techniques as...

11. miscellaneous rules for blocking/allowing More recent comments..

12. stop hotlinking, serve alternate content

13. block robots, rippers, and offline browsers Featured Content


14. more stupid blocking tricks CSS Reset Styles

15. even more scum-blocking tricks WordPress Plugins

16. password-protect directories WordPress Themes

17. password-protect files, directories, and more WordPress Loops

18. require SSL (secure sockets layer)

19. automatically CHMOD various file types


Popular Posts
20. disguise all file extensions
Wireless Internet: BlackBerry Curve as Bluetooth
21. limit file upload size Modem for OS-X Mac

22. disable script execution The Perishable Press 4G Blacklist

The New Clearfix Method


Usability
WordPress Plugin: Contact Coldform

1. minimize CSS image flicker in IE6 Category LiveBookmarks Plus

2. deploy custom error pages Book Giveaway: Print Version of Digging into
WordPress
3. provide a universal error document
BlogStats PCC Plugin
4. employ basic URL spelling check

5. force media downloads


Twitter Archive
6. display file source code
WordPress-powered Tweet Archive + Tools

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

7. redirect visitors during site development

8. provide password-prompt during site development

9. prevent access during specified time periods

Redirects

1. important note about redirecting via mod_rewrite

2. redirect from www-domain to non-www-domain

3. redirect from an old domain to a new domain

4. redirect string variations to a specific address

5. other fantastic redirect tricks

6. send visitors to a subdomain

7. more fun with RewriteCond & RewriteRule

8. more fun with Redirect 301 & RedirectMatch 301

WordPress

1. secure wordPress contact forms

2. wordpress permalinks

Random

1. activate SSI for HTML/SHTML file types

2. grant CGI access in a specific directory

3. disable magic_quotes_gpc for PHP enabled servers

4. enable MD5 digests

5. expression engine tricks

References

GENERAL INFORMATION [ ^ ]

.htaccess Definition 1 ^

Apache server software provides distributed (i.e., directory-level) configuration via Hypertext
Access files. These .htaccess files enable the localized fine-tuning of Apache’s universal
system-configuration directives, which are defined in Apache’s main configuration file. The
localized .htaccess directives must operate from within a file named .htaccess. The user must
have appropriate file permissions to access and/or edit the .htaccess file. Further, .htaccess
file permissions should never allow world write access — a secure permissions setting is “644”,
which allows universal read access and user-only write access. Finally, .htaccess rules apply to
the parent directory and all subdirectories. Thus to apply configuration rules to an entire website,
place the .htaccess file in the root directory of the site.

Commenting .htaccess Code ^

Comments are essential to maintaining control over any involved portion of code. Comments in

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

.htaccess code are fashioned on a per-line basis, with each line of comments beginning with a
pound sign #. Thus, comments spanning multiple lines in the .htaccess file require multiple
pound signs. Further, due to the extremely volatile nature of htaccess voodoo, it is wise to
include only alphanumeric characters (and perhaps a few dashes and underscores) in any
.htaccess comments.

Important Notes for .htaccess Noobs ^

As a configuration file, .htaccess is very powerful. Even the slightest syntax error (like a missing
space) can result in severe server malfunction. Thus it is crucial to make backup copies of
everything related to your site (including any original .htaccess files) before working with your
Hypertext Access file(s). It is also important to check your entire website thoroughly after making
any changes to your .htaccess file. If any errors or other problems are encountered, employ
your backups immediately to restore original functionality.

Performance Issues ^

.htaccess directives provide directory-level configuration without requiring access to Apache’s


main server cofiguration file (httpd.conf). However, due to performance and security concerns,
the main configuration file should always be used for server directives whenever possible. For
example, when a server is configured to process .htaccess directives, Apache must search every
directory within the domain and load any and all .htaccess files upon every document request.
This results in increased page processing time and thus decreases performance. Such a
performance hit may be unnoticeable for sites with light traffic, but becomes a more serious issue
for more popular websites. Therefore, .htaccess files should only be used when the main server
configuration file is inaccessible. See the “Performance Tricks” section of this article for more
information.

Regex Character Definitions for htaccess 2 ^

the # instructs the server to ignore the line. used for including comments. each line of
comments requires it’s own #. when including comments, it is good practice to use only letters,
numbers, dashes, and underscores. this practice will help eliminate/avoid potential server
parsing errors.

[F]

Forbidden: instructs the server to return a 403 Forbidden to the client.

[L]

Last rule: instructs the server to stop rewriting after the preceding directive is processed.

[N]

Next: instructs Apache to rerun the rewrite rule until all rewriting directives have been
achieved.

[G]

Gone: instructs the server to deliver Gone (no longer exists) status message.

[P]

Proxy: instructs server to handle requests by mod_proxy

[C]

Chain: instructs server to chain the current rule with the previous rule.

[R]

Redirect: instructs Apache to issue a redirect, causing the browser to request the
rewritten/modified URL.

[NC]

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

No Case: defines any associated argument as case-insensitive. i.e., "NC" = "No Case".

[PT]

Pass Through: instructs mod_rewrite to pass the rewritten URL back to Apache for further
processing.

[OR]

Or: specifies a logical "or" that ties two expressions together such that either one proving true
will cause the associated rule to be applied.

[NE]

No Escape: instructs the server to parse output without escaping characters.

[NS]

No Subrequest: instructs the server to skip the directive if internal sub-request.

[QSA]

Append Query String: directs server to add the query string to the end of the expression (URL).

[S=x]

Skip: instructs the server to skip the next "x" number of rules if a match is detected.

[E=variable:value]

Environmental Variable: instructs the server to set the environmental variable "variable" to
"value".

[T=MIME-type]

Mime Type: declares the mime type of the target resource.

[]

specifies a character class, in which any character within the brackets will be a match. e.g.,
[xyz] will match either an x, y, or z.

[]+

character class in which any combination of items within the brackets will be a match. e.g.,
[xyz]+ will match any number of x’s, y’s, z’s, or any combination of these characters.

[^]

specifies not within a character class. e.g., [^xyz] will match any character that is neither x, y,
nor z.

[a-z]

a dash (-) between two characters within a character class ([]) denotes the range of characters
between them. e.g., [a-zA-Z] matches all lowercase and uppercase letters from a to z.

a{n}

specifies an exact number, n, of the preceding character. e.g., x{3} matches exactly three x’s.

a{n,}

specifies n or more of the preceding character. e.g., x{3,} matches three or more x’s.

a{n,m}

specifies a range of numbers, between n and m, of the preceding character. e.g., x{3,7}
matches three, four, five, six, or seven x’s.

()

used to group characters together, thereby considering them as a single unit. e.g.,
(perishable)?press will match press, with or without the perishable prefix.

denotes the beginning of a regex (regex = regular expression) test string. i.e., begin argument
with the proceeding character.

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

denotes the end of a regex (regex = regular expression) test string. i.e., end argument with
the previous character.

declares as optional the preceding character. e.g., monzas? will match monza or monzas, while
mon(za)? will match either mon or monza. i.e., x? matches zero or one of x.

declares negation. e.g., “!string” matches everything except “string”.

a dot (or period) indicates any single arbitrary character.

instructs “not to” rewrite the URL, as in “...domain.com.* - [F]”.

matches one or more of the preceding character. e.g., G+ matches one or more G’s, while "+"
will match one or more characters of any kind.

matches zero or more of the preceding character. e.g., use “.*” as a wildcard.

declares a logical “or” operator. for example, (x|y) matches x or y.

escapes special characters ( ^ $ ! . * | ). e.g., use “\.” to indicate/escape a literal dot.

\.

indicates a literal dot (escaped).

/*

zero or more slashes.

.*

zero or more arbitrary characters.

^$

defines an empty string.

^.*$

the standard pattern for matching everything.

[^/.]

defines one character that is neither a slash nor a dot.

[^/.]+

defines any number of characters which contains neither slash nor dot.

http://

this is a literal statement — in this case, the literal character string, “http://”.

^domain.*

defines a string that begins with the term “domain”, which then may be proceeded by any
number of any characters.

^domain\.com$

defines the exact string “domain.com”.

-d

tests if string is an existing directory

-f

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

tests if string is an existing file

-s

tests if file in test string has a non-zero value

Redirection Header Codes ^

301 - Moved Permanently

302 - Moved Temporarily

403 - Forbidden

404 - Not Found

410 - Gone

ESSENTIALS [ ^ ]

Commenting your htaccess Files ^

It is an excellent idea to consistenly and logically comment your htaccess files. Any line in an
htaccess file that begins with the pound sign ( # ) tells the server to ignore it. Multiple lines
require multiple pounds and use letters/numbers/dash/underscore only:

# this is a comment
# each line must have its own pound sign
# use only alphanumeric characters along with dashes - and underscores _

Enable Basic Rewriting ^

Certain servers may not have “mod_rewrite” enabled by default. To ensure mod_rewrite (basic
rewriting) is enabled throughout your site, add the following line once to your site’s root htaccess
file:

# enable basic rewriting


RewriteEngine on

Enable Symbolic Links ^

Enable symbolic links (symlinks) by adding the following directive to the target directory’s
htaccess file. Note: for the FollowSymLinks directive to function, AllowOverride Options
privileges must be enabled from within the server configuration file (see proceeding paragraph for
more information):

# enable symbolic links


Options +FollowSymLinks

Enable AllowOverride ^

For directives that require AllowOverride in order to function, such as FollowSymLinks (see
above paragraph), the following directive must be added to the server configuration file. For
performance considerations, it is important to only enable AllowOverride in the specific directory
or directories in which it is required. In the following code chunk, we are enabling the
AllowOverride privs only in the specified directory (/www/replace/this/with/actual/directory).
Refer to this section for more information about AllowOverride and performance enhancement:

# enable allowoverride privileges


<Directory /www/replace/this/with/actual/directory>

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

 AllowOverride Options
</Directory>

Rename the htaccess File ^

Not every system enjoys the extension-only format of htaccess files. Fortunately, you can
rename them to whatever you wish, granted the name is valid on your system. Note: This
directive must be placed in the server-wide configuration file or it will not work:

# rename htaccess files


AccessFileName ht.access

Note: If you rename your htaccess files, remember to update any associated configuration
settings. For example, if you are protecting your htaccess file via FilesMatch, remember to
inform it of the renamed files:

# protect renamed htaccess files


<FilesMatch "^ht\.">
 Order deny,allow
 Deny from all
</FilesMatch>

Retain Rules Defined in httpd.conf ^

Save yourself time and effort by defining replicate rules for multiple virtual hosts once and only
once via your httpd.conf file. Then, simply instruct your target htaccess file(s) to inherit the
httpd.conf rules by including this directive:

RewriteOptions Inherit

PERFORMANCE [ ^ ]

Improving Performance via AllowOverride ^

Limit the extent to which htaccess files decrease performance by enabling AllowOverride only in
required directories. For example, if AllowOverride is enabled throughout the entire site, the
server must dig through every directory, searching for htaccess files that may not even exist. To
prevent this, we disable the AllowOverride in the site’s root htaccess file and then enable
AllowOverride only in required directories via the server config file (refer to this section for
more information). Note: if you do not have access to your site’s server config file and also need
AllowOverride privileges, do not use this directive:

# increase performance by disabling allowoverride


AllowOverride None

Improving Performance by Passing the Character Set ^

Prevent certain 500 error displays by passing the default character set parameter before you get
there. Note: replace the “utf-8” below with the charset that your site is using:

# pass the default character set


AddDefaultCharset utf-8

Improving Performance by Preserving Bandwidth ^

To increase performance on PHP enabled servers, add the following directive:

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

# preserve bandwidth for PHP enabled servers


<ifmodule mod_php4.c>
 php_value zlib.output_compression 16386
</ifmodule>

Disable the Server Signature ^

Here we are disabling the digital signature that would otherwise identify the server:

# disable the server signature


ServerSignature Off

Set the Server Timezone ^

Here we are instructing the server to synchronize chronologically according to the time zone of
some specified state:

# set the server timezone


SetEnv TZ America/Washington

Set the Email Address for the Server Administrator ^

Here we are specifying the default email address for the server administrator:

# set the server administrator email


SetEnv SERVER_ADMIN default@domain.com

Improve Site Transfer Speed by Enabling File Caching ^

The htaccess genius over at askapache.com explains how to dramatically improve your site’s
transfer speed by enabling file caching 3 . Using time in seconds* to indicate the duration for
which cached content should endure, we may generalize the htaccess rules as such (edit file
types and time value to suit your needs):

# cache images and flash content for one month


<FilesMatch ".(flv|gif|jpg|jpeg|png|ico|swf)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>

# cache text, css, and javascript files for one week


<FilesMatch ".(js|css|pdf|txt)$">
Header set Cache-Control "max-age=604800"
</FilesMatch>

# cache html and htm files for one day


<FilesMatch ".(html|htm)$">
Header set Cache-Control "max-age=43200"
</FilesMatch>

# implement minimal caching during site development


<FilesMatch "\.(flv|gif|jpg|jpeg|png|ico|js|css|pdf|swf|html|htm|txt)$">
Header set Cache-Control "max-age=5"
</FilesMatch>

# explicitly disable caching for scripts and other dynamic files

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
Header unset Cache-Control
</FilesMatch>

# alternate method for file caching


ExpiresActive On
ExpiresDefault A604800 # 1 week
ExpiresByType image/x-icon A2419200 # 1 month
ExpiresByType application/x-javascript A2419200 # 1 month
ExpiresByType text/css A2419200 # 1 month
ExpiresByType text/html A300 # 5 minutes
# disable caching for scripts and other dynamic files
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$">
ExpiresActive Off
</FilesMatch>

* Convert common time intervals into seconds:

300 = 5 minutes

2700 = 45 minutes

3600 = 1 hour

54000 = 15 hours

86400 = 1 day

518400 = 6 days

604800 = 1 week

1814400 = 3 weeks

2419200 = 1 month

26611200 = 11 months

29030400 = 1 year = never expires

Set the default language and character set ^

Here is an easy way to set the default language for pages served by your server (edit the
language to suit your needs):

# set the default language


DefaultLanguage en-US

Likewise, here we are setting the default character set (edit to taste):

# set the default character set


AddDefaultCharset UTF-8

Declare specific/additional MIME types ^

# add various mime types


AddType application/x-shockwave-flash .swf
AddType video/x-flv .flv
AddType image/x-icon .ico

Send character set and other headers without meta tags ^

# send the language tag and default character set


# AddType 'text/html; charset=UTF-8' html

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

AddDefaultCharset UTF-8
DefaultLanguage en-US

Limit server request methods to GET and PUT ^

# limit server request methods to GET and PUT


Options -ExecCGI -Indexes -All
RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD) RewriteRule .* - [F]

Selectively process files according to server request method ^

# process files according to server request method


Script PUT /cgi-bin/upload.cgi
Script GET /cgi-bin/download.cgi

Execute various file types through a cgi script ^

For those special occasions where certain file types need to be processed with some specific cgi
script, let em know who sent ya:

# execute all png files via png-script.cgi


Action image/png /cgi-bin/png-script.cgi

SECURITY [ ^ ]

Prevent Access to .htaccess ^

Add the following code block to your htaccess file to add an extra layer of security. Any attempts
to access the htaccess file will result in a 403 error message. Of course, your first layer of
defense to protect htaccess files involves setting htaccess file permissions via CHMOD to 644:

# secure htaccess file


<Files .htaccess>
 order allow,deny
 deny from all
</Files>

Prevent Acess to a Specific File ^

To restrict access to a specific file, add the following code block and edit the file name,
“secretfile.jpg”, with the name of the file that you wish to protect:

# prevent viewing of a specific file


<files secretfile.jpg>
 order allow,deny
 deny from all
</files>

Prevent acess to multiple file types ^

To restrict access to a variety of file types, add the following code block and edit the file types
within parentheses to match the extensions of any files that you wish to protect:

<FilesMatch "\.(htaccess|htpasswd|ini|phps|fla|psd|log|sh)$">
 Order Allow,Deny

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

 Deny from all


</FilesMatch>

Prevent Unauthorized Directory Browsing ^

Prevent unauthorized directory browsing by instructing the server to serve a “xxx Forbidden -
Authorization Required” message for any request to view a directory. For example, if your site is
missing it’s default index page, everything within the root of your site will be accessible to all
visitors. To prevent this, include the following htaccess rule:

# disable directory browsing


Options All -Indexes

Conversely, to enable directory browsing, use the following directive:

# enable directory browsing


Options All +Indexes

Likewise, this rule will prevent the server from listing directory contents:

# prevent folder listing


IndexIgnore *

And, finally, the IndexIgnore directive may be used to prevent the display of select file types:

# prevent display of select file types


IndexIgnore *.wmv *.mp4 *.avi *.etc

Change Default Index Page ^

This rule tells the server to search for and serve “business.html” as the default directory index.
This rule must exist in the htaccess files of the root directory for which you wish to replace the
default index file (e.g., “index.html”):

# serve alternate default index page


DirectoryIndex business.html

This rule is similar, only in this case, the server will scan the root directory for the listed files and
serve the first match it encounters. The list is read from left to right:

# serve first available alternate default index page from series


DirectoryIndex filename.html index.cgi index.pl default.htm

Disguise Script Extensions ^

To enhance security, disguise scripting languages by replacing actual script extensions with
dummy extensions of your choosing. For example, to change the “.foo” extension to “.php”,
add the following line to your htaccess file and rename all affected files accordingly:

# serve foo files as php files


AddType application/x-httpd-php .foo

# serve foo files as cgi files


AddType application/x-httpd-cgi .foo

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

Limit Access to the Local Area Network (LAN) ^

# limit access to local area network


<Limit GET POST PUT>
 order deny,allow
 deny from all
 allow from 192.168.0.0/33
</Limit>

Secure Directories by IP Address and/or Domain ^

In the following example, all IP addresses are allowed access except for 12.345.67.890 and
domain.com:

# allow all except those indicated here


<Limit GET POST PUT>
 order allow,deny
 allow from all
 deny from 12.345.67.890
 deny from .*domain\.com.*
</Limit>

In the following example, all IP addresses are denied access except for 12.345.67.890 and
domain.com:

# deny all except those indicated here


<Limit GET POST PUT>
 order deny,allow
 deny from all
 allow from 12.345.67.890
 allow from .*domain\.com.*
</Limit>

This is how to block unwanted visitors based on the referring domain. You can also save
bandwidth by blocking specific file types — such as .jpg, .zip, .mp3, .mpg — from specific
referring domains. Simply replace “scumbag” and “wormhole” with the offending domains of your
choice:

# block visitors referred from indicated domains


<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{HTTP_REFERER} scumbag\.com [NC,OR]
 RewriteCond %{HTTP_REFERER} wormhole\.com [NC,OR]
 RewriteRule .* - [F]
</ifModule>

Prevent or allow domain access for a specified range of IP addresses ^

There are several effective ways to block a range of IP addresses via htaccess. This first method
blocks an IP range specified by their CIDR (Classless Inter-Domain Routing) number. This
method is useful for blocking mega-spammers such as RIPE, Optinet, and others. If, for example,
you find yourself adding line after line of Apache deny directives for addresses beginning with the
same first few numbers, choose one of them and try a whois lookup . Listed within the whois
results will be the CIDR value representing every IP address associated with that particular
network. Thus, blocking via CIDR is an effective way to eloquently prevent all IP instances of the
offender from accessing your site. Here is a generalized example for blocking by CIDR (edit
values to suit your needs):

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

# block IP range by CIDR number


<Limit GET POST PUT>
 order allow,deny
 allow from all
 deny from 10.1.0.0/16
 deny from 80.0.0/8
</Limit>

Likewise, to allow an IP range by CIDR number:

# allow IP range by CIDR number


<Limit GET POST PUT>
 order deny,allow
 deny from all
 allow from 10.1.0.0/16
 allow from 80.0.0/8
</Limit>

Another effective way to block an entire range of IP addresses involves truncating digits until the
desired range is represented. As an IP address is read from left to right, its value represents an
increasingly specific address. For example, a fictitious IP address of 99.88.77.66 would designate
some uniquely specific IP address. Now, if we remove the last two digits (66) from the address, it
would represent any address beginning with the remaining digits. That is, 99.88.77 represents
99.88.77.1, 99.88.77.2, … 99.88.77.99, …etc. Likewise, if we then remove another pair of digits
from the address, its range suddenly widens to represent every IP address 99.88.x.y, where x
and y represent any valid set of IP address values (i.e., you would block 256*256 = 65,536
unique IP addresses). Following this logic, it is possible to block an entire range of IP addresses
to varying degrees of specificity. Here are few generalized lines exemplifying proper htaccess
syntax (edit values to suit your needs):

# block IP range by address truncation


<Limit GET POST PUT>
 order allow,deny
 allow from all
 deny from 99.88.77.66
 deny from 99.88.77.*
 deny from 99.88.*.*
 deny from 99.*.*.*
</Limit>

Likewise, to allow an IP range by address truncation:

# allow IP range by address truncation


<Limit GET POST PUT>
 order deny,allow
 deny from all
 allow from 99.88.77.66
 allow from 99.88.77.*
 allow from 99.88.*.*
 allow from 99.*.*.*
</Limit>

Block or allow multiple IP addresses on one line ^

Save a little space by blocking multiple IP addresses or ranges on one line. Here are few
examples (edit values to suit your needs):

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

# block two unique IP addresses


deny from 99.88.77.66 11.22.33.44
# block three ranges of IP addresses
deny from 99.88 99.88.77 11.22.33

Likewise, to allow multiple IP addresses or ranges on one line:

# allow two unique IP addresses


allow from 99.88.77.66 11.22.33.44
# allow three ranges of IP addresses
allow from 99.88 99.88.77 11.22.33

Miscellaneous rules for blocking and allowing IP addresses ^

Here are few miscellaneous rules for blocking various types of IP addresses. These rules may be
adapted to allow the specified IP values by simply changing the deny directive to allow. Check
’em out (edit values to suit your needs):

# block a partial domain via network/netmask values


deny from 99.1.0.0/255.255.0.0

# block a single domain


deny from 99.88.77.66

# block domain.com but allow sub.domain.com


order deny,allow
deny from domain.com
allow from sub.domain.com

Stop Hotlinking, Serve Alternate Content ^

To serve ‘em some unexpected alternate content when hotlinking is detected, employ the
following code, which will protect all files of the types included in the last line (add more types as
needed). Remember to replace the dummy path names with real ones. Also, the name of the
nasty image being served in this case is “eatme.jpe”, as indicated in the line containing the
RewriteRule. Please advise that this method will also block services such as FeedBurner from
accessing your images.

# stop hotlinking and serve alternate content


<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{HTTP_REFERER} !^$
 RewriteCond %{HTTP_REFERER} !^http://(www\.)?domain\.com/.*$ [NC]
 RewriteRule .*\.(gif|jpg)$ http://www.domain.com/eatme.jpe [R,NC,L]
</ifModule>

Note: To deliver a standard (or custom, if configured) error page instead of some nasty image of
the Fonz, replace the line containing the RewriteRule in the above htaccess directive with the
following line:

# serve a standard 403 forbidden error page


RewriteRule .*\.(gif|jpg)$ - [F,L]

Note: To grant linking permission to a site other than yours, insert this code block after the line
containing the “domain.com” string. Remember to replace “goodsite.com” with the actual site
domain:

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

# allow linking from the following site


RewriteCond %{HTTP_REFERER} !^http://(www\.)?goodsite\.com/.*$ [NC]

Block Evil Robots, Site Rippers, and Offline Browsers ^

Eliminate some of the unwanted scum from your userspace by injecting this handy block of code.
After such, any listed agents will be denied access and receive an error message instead. Please
advise that there are much more comprehensive lists available this example has been truncated
for business purposes. Note: DO NOT include the “[OR]” on the very last RewriteCond or your
server will crash, delivering “500 Errors” to all page requests.

# deny access to evil robots site rippers offline browsers and other nasty scum
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} ^Anarchie [OR]
RewriteCond %{HTTP_USER_AGENT} ^ASPSeek [OR]
RewriteCond %{HTTP_USER_AGENT} ^attach [OR]
RewriteCond %{HTTP_USER_AGENT} ^autoemailspider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xaldon\ WebSpider [OR]
RewriteCond %{HTTP_USER_AGENT} ^Xenu [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus.*Webster [OR]
RewriteCond %{HTTP_USER_AGENT} ^Zeus
RewriteRule ^.* - [F,L]

Or, instead of delivering a friendly error message (i.e., the last line), send these bad boys to the
hellish website of your choice by replacing the RewriteRule in the last line with one of the
following two examples:

# send em to a hellish website of your choice


RewriteRule ^.*$ http://www.hellish-website.com [R,L]

Or, to send em to a virtual blackhole of fake email addresses:

# send em to a virtual blackhole of fake email addresses


RewriteRule ^.*$ http://english-61925045732.spampoison.com [R,L]

You may also include specific referrers to your blacklist by using HTTP_REFERER. Here, we use the
infamously scummy domain, “iaea.org” as our blocked example, and we use “yourdomain” as
your domain (the domain to which you are blocking iaea.org):

RewriteCond %{HTTP_REFERER} ^http://www.iaea.org$


RewriteRule !^http://[^/.]\.yourdomain\.com.* - [F,L]

More Stupid Blocking Tricks ^

Note: Although these redirect techniques are aimed at blocking and redirecting nasty scumsites,
the directives may also be employed for friendly redirection purposes:

# redirect any request for anything from spamsite to differentspamsite


RewriteCond %{HTTP_REFERER} ^http://.*spamsite.*$ [NC]
RewriteRule .* http://www.differentspamsite.com [R]

# redirect all requests from spamsite to an image of something at


differentspamsite
RewriteCond %{HTTP_REFERER} ^http://.*spamsite.*$ [NC]
RewriteRule .* http://www.differentspamsite/something.jpg [R]

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

# redirect traffic from a certain address or range of addresses to another site


RewriteCond %{REMOTE_ADDR} 192.168.10.*
RewriteRule .* http://www.differentspamsite.com/index.html [R]

Even More Scum-Blocking Tricks ^

Here is a step-by-step series of code blocks that should equip you with enough knowledge to
block any/all necessary entities. Read through the set of code blocks, observe the patterns, and
then copy, combine and customize to suit your specific scum-blocking needs:

# set variables for user agents and referers and ip addresses


SetEnvIfNoCase User-Agent ".*(user-agent-you-want-to-block|php/perl).*"
BlockedAgent
SetEnvIfNoCase Referer ".*(block-this-referrer|and-this-referrer|and-this-
referrer).*" BlockedReferer
SetEnvIfNoCase REMOTE_ADDR ".*(666.666.66.0|22.22.22.222|999.999.99.999).*"
BlockedAddress

# set variable for any class B network coming from a given netblock
SetEnvIfNoCase REMOTE_ADDR "66.154.*" BlockedAddress

# set variable for two class B networks 198.25.0.0 and 198.26.0.0


SetEnvIfNoCase REMOTE_ADDR "198.2(5|6)\..*" BlockedAddress

# deny any matches from above and send a 403 denied


<Limit GET POST PUT>
 order deny,allow
 deny from env=BlockedAgent
 deny from env=BlockedReferer
 deny from env=BlockedAddress
 allow from all
</Limit>

Password-Protect Directories ^

Here is an excellent online tool for generating the necessary elements for a password-protected
directory:

# password protect directories


htaccess Password Generator

Password-protect Files, Directories, and More.. ^

Secure site contents by requiring user authentication for specified files and/or directories. The
first example shows how to password-protect any single file type that is present beneath the
directory which houses the htaccess rule. The second rule employs the FilesMatch directive to
protect any/all files which match any of the specified character strings. The third rule
demonstrates how to protect an entire directory. The fourth set of rules provides password-
protection for all IP’s except those specified. Remember to edit these rules according to your
specific needs.

# password-protect single file


<Files secure.php>
AuthType Basic
AuthName "Prompt"

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

AuthUserFile /home/path/.htpasswd
Require valid-user
</Files>

# password-protect multiple files


<FilesMatch "^(execute|index|secure|insanity|biscuit)*$">
AuthType basic
AuthName "Development"
AuthUserFile /home/path/.htpasswd
Require valid-user
</FilesMatch>

# password-protect the directory in which this htaccess rule resides


AuthType basic
AuthName "This directory is protected"
AuthUserFile /home/path/.htpasswd
AuthGroupFile /dev/null
Require valid-user

# password-protect directory for every IP except the one specified


# place in htaccess file of a directory to protect that entire directory
AuthType Basic
AuthName "Personal"
AuthUserFile /home/path/.htpasswd
Require valid-user
Allow from 99.88.77.66
Satisfy Any

Require SSL (Secure Sockets Layer) ^

Here is an excellent method for requiring SSL (via askapache.com 3 ):

# require SSL
SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "domain.tld"
ErrorDocument 403 https://domain.tld

# require SSL without mod_ssl


RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

Automatically CHMOD Various File Types ^

This method is great for ensuring the CHMOD settings for various file types. Employ the following
rules in the root htaccess file to affect all specified file types, or place in a specific directory to
affect only those files (edit file types according to your needs):

# ensure CHMOD settings for specified file types


# remember to never set CHMOD 777 unless you know what you are doing
# files requiring write access should use CHMOD 766 rather than 777
# keep specific file types private by setting their CHMOD to 400
chmod .htpasswd files 640
chmod .htaccess files 644
chmod php files 600

Disguise all file extensions ^

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

This method will disguise all file types (i.e., any file extension) and present them as .php files (or
whichever extension you choose):

# diguise all file extensions as php


ForceType application/x-httpd-php

Protect against denial-of-service (DOS) attacks by limiting file upload size ^

One method to help protect your server against DOS attacks involves limiting the maximum
allowable size for file uploads. Here, we are limiting file upload size to 10240000 bytes, which is
equivalent to around 10 megabytes. For this rule, file sizes are expressed in bytes. Check here
for help with various file size conversions. Note: this code is only useful if you actually allow
users to upload files to your site.

# protect against DOS attacks by limiting file upload size


LimitRequestBody 10240000

Secure directories by disabling execution of scripts ^

Prevent malicious brainiacs from actively scripting secure directories by adding the following rules
to the representative htaccess file (edit file types to suit your needs):

# secure directory by disabling script execution


AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI

USABILITY TRICKS [ ^ ]

Minimize CSS Image Flicker in IE6 ^

Add the following htaccess rules to minimize or even eliminate CSS background-image “flickering”
in MSIE6:

# minimize image flicker in IE6


ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/png A2592000

Deploy Custom Error Pages ^

Replicate the following patterns to serve your own set of custom error pages. Simply replace the
“/errors/###.html” with the correct path and file name. Also change the “###” preceding the
path to summon pages for other errors. Note: your custom error pages must be larger than 512
bytes in size or they will be completely ignored by Internet Explorer:

# serve custom error pages


ErrorDocument 400 /errors/400.html
ErrorDocument 401 /errors/401.html
ErrorDocument 403 /errors/403.html
ErrorDocument 404 /errors/404.html
ErrorDocument 500 /errors/500.html

Provide a Universal Error Document ^

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

# provide a universal error document


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /dir/error.php [L]

Employ Basic URL Spelling Check ^

This bit of voodoo will auto-correct simple spelling errors in the URL:

# automatically corect simple speling erors


<IfModule mod_speling.c>
 CheckSpelling On
</IfModule>

Instruct browser to download multimedia files rather than display them ^

Here is a useful method for delivering multimedia file downloads to your users. Typically,
browsers will attempt to play or stream such files when direct links are clicked. With this method,
provide a link to a multimedia file and a dialogue box will provide users the choice of saving the
file or opening it. Here are a few htaccess rules demonstrating the technique (edit file types
according to your specific needs):

# instruct browser to download multimedia files


AddType application/octet-stream .avi
AddType application/octet-stream .mpg
AddType application/octet-stream .wmv
AddType application/octet-stream .mp3

Instruct server to display source code for dynamic file types ^

There are many situations where site owners may wish to display the contents of a dynamic file
rather than executing it as a script. To exercise this useful technique, create a directory in which
to place dynamic files that should be displayed rather than executed, and add the following line
of code to the htaccess file belonging to that directory. This method is known to work for .pl,
.py, and .cgi file-types. Here it is:

RemoveHandler cgi-script .pl .py .cgi

Redirect visitors to a temporary site during site development ^

During web development, maintenance, or repair, send your visitors to an alternate site while
retaining full access for yourself. This is a very useful technique for preventing visitor confusion
or dismay during those awkward, web-development moments. Here are the generalized htaccess
rules to do it (edit values to suit your needs):

# redirect all visitors to alternate site but retain full access for you
ErrorDocument 403 http://www.alternate-site.com
Order deny,allow
Deny from all
Allow from 99.88.77.66

Provide a password prompt for visitors during site development ^

Here is another possible solution for "hiding" your site during those private, site-under-
construction moments. Here we are instructing Apache to provide visitors with a password
prompt while providing open access to any specifically indicated IP addresses or URL’s. Edit the
following code according to your IP address and other development requirements (thanks to

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

Caleb at askapache.com for sharing this trick 3 ):

# password prompt for visitors


AuthType basic
AuthName "This site is currently under construction"
AuthUserFile /home/path/.htpasswd
AuthGroupFile /dev/null
Require valid-user
# allow webmaster and any others open access
Order Deny,Allow
Deny from all
Allow from 111.222.33.4
Allow from favorite.validation/services/
Allow from googlebot.com
Satisfy Any

Prevent file or directory access according to specified time periods ^

Prevent viewing of all pictures of Fonzi during the midnight hour — or any files during any time
period — by using this handy htaccess ruleset:

# prevent access during the midnight hour


RewriteCond %{TIME_HOUR} ^12$
RewriteRule ^.*$ - [F,L]

# prevent access throughout the afternoon


RewriteCond %{TIME_HOUR} ^(12|13|14|15)$
RewriteRule ^.*$ - [F,L]

REDIRECT TRICKS [ ^ ]

Important Note About Redirecting via mod_rewrite ^

For all redirects using the mod_rewrite directive, it is necessary to have the RewriteEngine
enabled. It is common practice to enable the mod_rewrite directive in either the server
configuration file or at the top of the site’s root htaccess file. If the mod_rewrite directive is not
included in either of these two places, it should be included as the first line in any code block that
utilizes a rewrite function (i.e., mod_rewrite), but only needs to be included once for each
htaccess file. The proper mod_rewrite directive is included here for your convenience, but may or
may not also be included within some of the code blocks provided in this article:

# initialize and enable rewrite engine


RewriteEngine on

Redirect from http://www.domain.com to http://domain.com ^

This method uses a “301 redirect” to establish a permanent redirect from the “www-version” of a
domain to its respectively corresponding “non-www version”. Be sure to test immediately after
preparing 301 redirects and remove it immediately if any errors occur. Use a “server header
checker ” to confirm a positive 301 response. Further, always include a trailing slash “/” when
linking directories. Finally, be consistent with the “www” in all links (either use it always or
never).

# permanently redirect from www domain to non-www domain


RewriteEngine on
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} ^www\.domain\.tld$ [NC]

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

RewriteRule ^(.*)$ http://domain.tld/$1 [R=301,L]

Redirect from http://old-domain.com to http://new-domain.com ^

For a basic domain change from “old-domain.com” to “new-domain.com” (and folder/file names
have not been changed), use the Rewrite rule to remap the old domain to the new domain.
When checking the redirect live, the old domain may appear in the browser’s address bar. Simply
check an image path (right-click an image and select “properties”) to verify proper redirection.
Remember to check your site thoroughly after implementing this redirect.

# redirect from old domain to new domain


RewriteEngine On
RewriteRule ^(.*)$ http://www.new-domain.com/$1 [R=301,L]

Redirect String Variations to a Specific Address ^

For example, if we wanted to redirect any requests containing the character string, “perish”, to
our main page at http://perishablepress.com/, we would replace “some-string” with “perish” in
the following code block:

# redirect any variations of a specific character string to a specific address


RewriteRule ^some-string http://www.domain.com/index.php/blog/target [R]

Here are two other methods for accomplishing string-related mapping tasks:

# map URL variations to the same directory on the same server


AliasMatch ^/director(y|ies) /www/docs/target

# map URL variations to the same directory on a different server


RedirectMatch ^/[dD]irector(y|ies) http://domain.com

Other Fantastic Redirect Tricks ^

Redirect an entire site via 301:

# redirect an entire site via 301


redirect 301 / http://www.domain.com/

Redirect a specific file via 301:

# redirect a specific file via 301


redirect 301 /current/currentfile.html http://www.newdomain.com/new/newfile.html

Redirect an entire site via permanent redirect:

# redirect an entire site via permanent redirect


Redirect permanent / http://www.domain.com/

Redirect a page or directory via permanent redirect:

# redirect a page or directory


Redirect permanent old_file.html http://www.new-domain.com/new_file.html
Redirect permanent /old_directory/ http://www.new-domain.com/new_directory/

Redirect a file using RedirectMatch:

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

# redirect a file using RedirectMatch


RedirectMatch 301 ^.*$ http://www.domain.com/index.html

Note: When redirecting specific files, use Apache‘s Redirect rule for files within the same
domain. Use Apache‘s RewriteRule for any domains, especially if they are different. The
RewriteRule is more powerful than the Redirect rule, and thus should serve you more
effectively.

Thus, use the following for a stronger, harder page redirection (first line redirects a file, second
line a directory, and third a domain):

# redirect files directories and domains via RewriteRule


RewriteRule http://old-domain.com/old-file.html http://new-domain.com/new-
file.html
RewriteRule http://old-domain.com/old-dir/ http://new-domain.com/new-dir/
RewriteRule http://old-domain.com/ http://new-domain.com/

Send visitors to a subdomain ^

This rule will ensure that all visitors are viewing pages via the subdomain of your choice. Edit the
"subdomain", "domain", and "tld" to match your subdomain, domain, and top-level domain
respectively:

# send visitors to a subdomain


RewriteCond %{HTTP_HOST} !^$
RewriteCond %{HTTP_HOST} !^subdomain\.domain\.com$ [NC]
RewriteRule ^/(.*)$ http://subdomain.domain.tld/$1 [L,R=301]

More fun with RewriteCond and RewriteRule ^

# rewrite only if the file is not found


RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)special\.html?$ cgi-bin/special/special-html/$1

# rewrite only if an image is not found


RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule images/special/(.*).gif cgi-bin/special/mkgif?$1

# seo-friendly rewrite rules for various directories


RewriteRule ^(.*)/aud/(.*)$ $1/audio-files/$2 [L,R=301]
RewriteRule ^(.*)/img/(.*)$ $1/image-files/$2 [L,R=301]
RewriteRule ^(.*)/fla/(.*)$ $1/flash-files/$2 [L,R=301]
RewriteRule ^(.*)/vid/(.*)$ $1/video-files/$2 [L,R=301]

# broswer sniffing via htaccess environmental variables


RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*
RewriteRule ^/$ /index-for-mozilla.html [L]
RewriteCond %{HTTP_USER_AGENT} ^Lynx.*
RewriteRule ^/$ /index-for-lynx.html [L]
RewriteRule ^/$ /index-for-all-others.html [L]

# redirect query to Google search


Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_URI} .google\.php*

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

RewriteRule ^(.*)$ ^http://www.google.com/search?q=$1 [R,NC,L]

# deny request according to the request method


RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD)$ [NC]
RewriteRule ^.*$ - [F]

# redirect uploads to a better place


RewriteCond %{REQUEST_METHOD} ^(PUT|POST)$ [NC]
RewriteRule ^(.*)$ /cgi-bin/upload-processor.cgi?p=$1 [L,QSA]

More fun with Redirect 301 and RedirectMatch 301 ^

# seo friendly redirect for a single file


Redirect 301 /old-dir/old-file.html http://domain.com/new-dir/new-file.html

# seo friendly redirect for multiple files


# redirects all files in dir directory with first letters xyz
RedirectMatch 301 /dir/xyz(.*) http://domain.com/$1

# seo friendly redirect entire site to a different domain


Redirect 301 / http://different-domain.com

WORDPRESS TRICKS [ ^ ]

Secure WordPress Contact Forms ^

Protect your insecure WordPress contact forms against online unrighteousness by verifying the
domain from whence the form is called. Remember to replace the “domain.com” and
“contact.php” with your domain and contact-form file names, respectively.

# secure wordpress contact forms via referrer check


RewriteCond %{HTTP_REFERER} !^http://www.domain.com/.*$ [NC]
RewriteCond %{REQUEST_POST} .*contact.php$
RewriteRule .* - [F]

WordPress Permalinks ^

In our article, The htaccess rules for all WordPress Permalinks, we revealed the precise htaccess
directives used by the WordPress blogging platform for permalink functionality. Here, for the sake
of completeness, we repeat the directives only. For more details please refer to the original
article:

If WordPress is installed in the site’s root directory, WordPress creates and uses the following
htaccess directives:

# BEGIN WordPress
<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /index.php [L]
</IfModule>
# END WordPress

If WordPress is installed in some subdirectory “foo”, WordPress creates and uses the following

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

htaccess directives:

# BEGIN WordPress
<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /foo/
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteRule . /foo/index.php [L]
</IfModule>
# END WordPress

RANDOM TRICKS [ ^ ]

Activate SSI for HTML/SHTML file types: ^

# activate SSI for HTML and or SHTML file types


AddType text/html .html
AddType text/html .shtml
AddHandler server-parsed .html
AddHandler server-parsed .shtml
AddHandler server-parsed .htm

Grant CGI access in a specific directory: ^

# grant CGI access in a specific directory


Options +ExecCGI
AddHandler cgi-script cgi pl
# to enable all scripts in a directory use the following
SetHandler cgi-script

Disable magic_quotes_gpc for PHP enabled servers: ^

# turn off magic_quotes_gpc for PHP enabled servers


<ifmodule mod_php4.c>
 php_flag magic_quotes_gpc off
</ifmodule>

Enable MD5 digests: ^

Note: enabling this option may result in a relative decrease in server performance.

# enable MD5 digests via ContentDigest


ContentDigest On

Expression Engine Tricks: ^

# send Atom and RSS requests to the site docroot to be rewritten for
ExpressionEngine
RewriteRule .*atom.xml$ http://www.yoursite.com/index.php/weblog/rss_atom/ [R]
RewriteRule .*rss.xml$ http://www.yoursite.com/index.php/weblog/rss_2.0/ [R]

# cause all requests for index.html to be rewritten for ExpressionEngine


RewriteRule /.*index.html$ http://www.domain.com/index.php [R]

REFERENCES

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

1 Wikipedia htaccess Resource

2 Apache Cookbook

3 Ultimate htaccess Article

More on regular expressions

Apache htaccess Reference

Apache htaccess Tutorial

Apache mod_rewrite

htaccess Forum

Behind the Scenes with htaccess

Automatic htaccess file generator

Short URL: http://tinyurl.com/yj5wuh 497252 visits

Post #15 categorized as Websites, last updated on Apr 2, 2007


Tagged with apache, htaccess, mod_rewrite, notes, plus, tricks, upgrade,
WordPress

ABOUT THE AUTHOR

Jeff Starr is a web developer, graphic designer and content producer with over
10 years of experience and a passion for quality and detail. Jeff is co-author of the
book Digging into WordPress and strives to help people be the best they can be on
the Web. + Follow Jeff on Twitter and subscribe to Perishable Press for quality web-
design content delivered fresh.

SHARE THIS ARTICLE

RELATED ARTICLES

Stupid htaccess Tricks Redux

HTAccess Password-Protection Tricks

Stupid htaccess Trick: Enable File or Directory Access to Your Password-Protected Site

htaccess Combo Pack: WordPress Permalinks and non-www Redirect

Permanently Redirect a Specific IP Request for a Single Page via htaccess

htaccess Redirect to Maintenance Page

Stupid Twitter Tricks

116 Responses

Lead #1
Very nice… this is just the overview that pretty much says it all…. Great
work !

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

Perishable #2
My pleasure! :)

Deep Singh #3
Absolutely good contents really helpful

Perishable #4
At your service! In fact, I appreciate the kind remarks so much that I am
planning to update this post with even more stupid htaccess tricks, including
new redirect and blocking tips as well as some very useful character
information.

m0n #5
UPDATE: We have completely rewritten this entire article, which now
includes almost twice as many stupid htaccess tricks, a nice library of regex
character definitions, and even a handy table of contents for easy
navigation. - Enjoy!

mattems #6
excellent!! just what i needed to get through those stupid htaccess issues !!

great work!

Perishable #7
You are too kind, mattems!

scandiman #8
Fantastic resource! Helped resolve many questions, but I remain totally
stumped on one rewrite I am trying to accomplish.

Currently, I have a CMS that does Search Engine Friendly URLs using the
following htaccess code:

RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ /index.php?q=$1 [L, QSA]

A click to the home page will give me the URL "mydomain.com/index.html"

I am trying to rewrite that URL to just give me "mydomain.com/" Is this


possible in the htaccess file considering the CMS is using it to rewrite the
URL’s as well? Or should I look into hacking the CMS?

Any help from an htaccess guru is appreciated!

Perishable #9
Hei scandiman,

Have you tried:

# redirect from index.html to /


Options +FollowSymLinks

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

RewriteEngine on
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.html\ HTTP/
RewriteRule ^index\.html$ http://mydomain.com/ [R=301,L]

Employing the "THE_REQUEST" server variable, the pattern will match against
the client request header only for the original URI request, thereby
restricting redirection to the default index page.

H.Walther #10
This is a great article! Thank you very much!!!

Instead of disguiseing script extensions, what is the best way to completely


remove it? Say www.foo.com/foo.php should be www.foo.com/foo?

Randy Gille #11


Email me here if you need any help with this:

slayer1001@gmail.com

Thanks!

Douglas Kemp #12


Absolutely brilliat work mate, this is a fanstasic .htacess resource.

Gabe Trann #13


Yes this is by far probably one of the best htaccess tuts.. nice work!

Oh heres another good one -


http://www.askapache.com/2006/htaccess/
htaccesselite-ultimate-htaccess-article.html.

Perishable #14
Thank you both for your encouraging comments — they inspire us to expand
further the scope of this htaccess reference. In fact, we have already written
up several additional rules and examples, and are simply waiting for a break
in the schedule to incorporate them here.

Happy Holidays!

Maria Langer #15


Thanks so much for putting up this very easy to understand guide!

MrLeN #16
Is it possible to redirect people from a particular country? ie: I might want
people who live in china to be recognised and automatically redirected to a
chinese page, or people who libe in germany to be automatically redirected
to a german page.

Perishable #17
MrLeN,
Yes, of course.. it is possible to execute country-specific redirects. If you
have GeoIP Apache API configured on your server, simply extrapolate the
following:

RewriteEngine on

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

RewriteCond %{ENV:GEOIP_COUNTRY_CODE} MX [NC]


RewriteRule ^$ index.mx.php [L]

This method employs country codes (we used Mexico in the example).

Of course, you could also redirect based on country-specific TLD or even IP


addresses.

Bad Monkey #18


I am trying to deny from a particular host, and for a time I even want to
deny an entire top-level domain.
E.g. deny from .nz
(new zealand)
But it does not work. Access is still allowed.
Similarly deny from myhost.ext does not work.
It does work with my IP.
Any ideas?

Perishable #19
Bad Monkey,
I need to see the htaccess code you are using.. htaccess rules are super-
sensitive — many problems are solved by simply correcting subtle errors in
syntax, order, etc.

Bad Monkey #20


Simply one line…
deny from 124.197.12.164
works, that is my IP and it bans me, but
deny from .nz
or
deny from .callplus.net.nz
(my host) does not.
Reverse DNS on my ip gives
124-197-12-164.callplus.net.nz
so what am I missing?

Perishable #21
You may want to try it within the following context:

<Limit GET POST>


order allow,deny
allow from all
deny from .nz
deny from .callplus.net.nz
</Limit>

If that still does not work, you might try a RewriteRule instead:

RewriteEngine on
Options +FollowSymlinks
RewriteCond %{HTTP_REFERER} ^(.*)\.nz [NC]
RewriteRule ^(.*)$ - [F,L]

css menus #22


nice post, helped a lot, thank you!

Perishable #23
My pleasure!

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

john #24
exceedingly helpful list for a newb like me.

thank you!

Perishable #25
Thank you for kind words, john! It is our pleasure to help people with
htaccess, and the positive feedback really inspires us to do our best.. ;)
- Cheers!

Iiro Krankka #26


You rock, dude! This is most comprehensive list of tricks I’ve ever seen!

joko #27
thanks for the trick. even a should translate to my language first.regards

K-len #28
how to redirect
http://abc.com
to
http://abc.com/abc/
I’ve tried your method but nothing happen.

Vlad #29
lol is it htaccess time? Found 7 htaccess tips yesterday and now stumble on
this post … Great work, recently struggled with severe performance
problems so this is indeed helpful.

Riquez #30
This page is an awesome resource. Thank you.
Bookmarked

sus #31
Very Nice. Thank you.

Jason Wagner #32


Omg… thank you SOOO MUCH!!!! I’ve been looking for a resource like this
one for MONTHS. Bookmarked this on my del.icio.us real quick…

THANK YOU!! :)

Larry Adamiec #33

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

I am trying to password protect a single file in a directory but the entire


directory is being protected. Here are the contents of the .htaccess file:

AuthType Basic
AuthName SecuredWebPages
AuthUserFile /opt/content/web/sites/ck/htaccess_users/mentor
require valid-user

I am using Sun Java Web Server Version 6.1 as the web server on a Solaris
10 server. What am I doing wrong?

Perishable #34
Larry,

You need to target the file to be protected with a <Files secure.php>


container, where "secure.php" is the target file. Here is an example:

<Files secure.php>
AuthType Basic
AuthName "Prompt"
AuthUserFile /home/path/.htpasswd
Require valid-user
</Files>

[ more information ]

Jer #35
You are a god.

dman #36
Great Information!
Thanks for taking time to put this informative post together.
———-
but I do have a stumper for you. My BIG problem are these Hotlinking
thieves. Do you know that my host just sent me a $2000 bandwidth bill for
April? And I cant afford that. So we dug a little and found that my images &
mpg clips were being Hotlinked. Not just a little, it was ALOT! and I’ve tried
to do everything I can, I even bought AHL from antihotlinking.com to
protect my mpg clips, but these Leechers are STILL getting through. So I’m
sitting here the other day frustrated out of my mind - and something came
to me, but before I tell you what came to me, I’ve pasted my present
.htaccess code below (I only changed the domains):
——————————-

Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://mydomain.tld.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://www.mydomain.tld.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www\.)?
myfriendspage.tld(/)?.*$ [NC]
RewriteRule .*\.(gif|jpg|jpeg|bmp|wmv|mpg)$
http://www.mydomain.tld [R,NC]
ErrorDocument 400 http://www.myaffiliate.tld
ErrorDocument 401 http://www.myaffiliate.tld
ErrorDocument 500 http://www.myaffiliate.tld
ErrorDocument 403 http://www.myaffiliate.tld
ErrorDocument 404 http://www.myaffiliate.tld
ErrorDocument 503 http://www.myaffiliate.tld
order allow,deny
allow from all

——————————-

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

I’ve obviously got major problems in the code above. And I have no clue
where or what to even do about it.

Oh - sorry, let me get back to that BIG idea that came to me. Ya see - in
my page source code, I can either use a “reletive” or the “full” path to my
images & mpgs. But these Hotlinkers have to use the “full” path if they want
to hotlink anything. So is there a way to configure the .htaccess code to
ONLY allow from “reletive” paths which obviously would be from me? Then -
block or redirect any hotlinker using pages with “Full” paths to my files? I
dont know. Cause to me, even if theres no referrer info or whatever, that
hotlinker MUST use the full path to my files. I mean the server must be able
to differentiate between someone (hotlinker) trying to get in to my server
externally as opposed to someone internally - for example - like one of my
legitimate customers whose landed on one of my advertisment pages
already.. Wow I really hope this all makes sense. Please let me know what
you think.
Thanks again,
Dman

Andy Moore #37


That’s simply the best collection of htaccess tricks I’ve ever seen!

Perishable #38
dman,
Of course! For more information, check out this section of our article. It
outlines the entire process that seems to work fine for just about everyone
on the Internet (you need to be running Apache, of course). As for your
idea concerning relative paths, that is essentially the same method
employed by the htaccess rules outlined in the linked section. All relative
links on a domain must share the same domain (by definition). Therefore, if
we grant access only to a specific domain (or domains), only referrers from
the allowed domain have access, regardless of the type of link. I hope this
helps!

DLa #39
Thank you for taking the time to assemble this incredible htaccess resource.
We continue to use several of these extremely helpful htaccess tricks on our
site. Two toots to the wind!

0racle #40
Sir Perishable,
A successful run, wouldn’t you say? This article has enjoyed plenty of use!
Now, don’t you think it’s time to publish the bleeding thing and become rich
and famous? Ha! Don’t make me laugh, Perishable. Nevertheless, screaming
applause for these wonderfully stupid htaccess tricks!

Perishable #41
Indeed! Actually, I have been thinking about putting together an offline (i.e.,
printed) version of Stupid htaccess Tricks. Perhaps the time is growing near
for something of that nature to unfold. The thing is, the article itself is a
100% free resource available anytime, anywhere. A book almost seems
superfluous these days, especially when you consider actually paying for
one. Who knows, maybe something will spring forth and inspire me to
publish. Stay tuned..

August Klotz #42


Jeff,
Thank you for providing this excellent htaccess resource. I find the code to

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

be top-notch, and the examples are clear, concise, and easy to understand.
My only question is when are you going to share the contents of your own
htaccess file for the benefit of others? I am certain it would be a valuable
resource. Incidentally, I second the motion for a printed version of the
article. I, for one, would be thrilled to obtain a copy!
Cheers,
August

m0n #43
I second the motion! Let’s share the htaccess rules used for
perishablepress.com. If anything, the vast htaccess ruleset blocking
spammers, scrapers, and badbots would surely be helpful. As for the book
idea.. sure, sounds great, but extra time seems like a luxury we just can’t
afford these days.

sandy #44
I’m a PHP developer from india. I have to work on dynamic subdomain
creation process via php. I need to create folders of users who registers on
site. And server platform is windows and control panel is plesk.

For time being i have created user folders like:


http://domain.tld/shop_stores/sandy/
http://domain.tld/shop_stores/mike/
http://domain.tld/shop_stores/john/

but i want to display as


http://sandy.domain.tld/
http://mike.domain.tld/
http://john.domain.tld/

Also wherever i want to give href link i will be able to give


http://sandy.domain.tld/

So can anyone please help me or guide how to do this kind of functionality.


Thanks in advance.

Alison #45
this is very useful content. I have one issue to which I have not been able
to find a solution. I want a permanent redirect to happen for a single page
when requested from a specific IP. Example:

Visitor from IP: 192:168:0:1


requests for page name www.url.com/abc.htm
I want him to go to www.url.com/xyz.htm

Visitors for all other IP’s should NOT get redirected.

Can this be accomplished using htaccess file?

Perishable #46
Alison,

Sure, try using this:

RewriteEngine On
RewriteBase /
RewriteCond %{REMOTE_HOST} 123\.123\.123\.123
RewriteCond %{REQUEST_URI} /requested-page\.html$
RewriteRule .* /just-for-you.html [R=301,L]

Simply edit the IP address, requested page, and redirect page.


Should perform exactly as specified.

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

John Joe #47


For over 2 years I’ve requested that my host block hotlinks - and all they’ve
ever managed to do is either block all images or just block Wordpress

Many thanks for the tips and tricks here - I’ve implented a few and as soon
as I eat more spinach I’ll be doing it some more! Many thanks for an
excellent, funny, informative article.

PS - I expect similar praise for my 2 bit site :-)

sandy #48
Hi Friends,

Please anybody respond to my question. Comments #81. I need it very


urgent. Please give me some solution.

Peter #49
This is a great post, thank you for sharing it.

I wonder if you could clarify something?

In the seo friendly rewrite rule for various directories, you have;

RewriteRule ^(.*)/aud/(.*)$ $1/audio-files/$2 [L,R=301]

which appears to pick up everything in the original request before “/aud/”


(including the domain) and add it to the beginning of the new folder path,
which makes perfect sense to me.

But, in the old domain to new domain redirect you have;

RewriteRule ^(.*)$ http://www.new-domain.com/$1 [R=301,L]

which also appears to pick up everything in the original request and then
add it to the end of the new domain.

My confusion is why the old domain to new domain rule doesn’t end up
adding the complete original request (including domain) onto the end of the
new domain name, rather than just the url?

Does that make sense?

Perishable #50
John Joe,

Thanks for the kind remarks. It is always great to get positive feedback, as
you should be well aware of considering the excellence and awesomeness of
your website! :)

Perishable #51
Peter,

If I understand you correctly, you are asking why the entire URL of the old
domain is not appended to the end of the new domain..?

If so, it is an excellent question. In both RewriteRule examples, the domain


is assumed, and is therefore not included in the matching variable ($1).

In the “SEO-friendly” case, the RewriteRule, considering only the URL


information appearing after the domain, redirects anything matching the
target string.

Similarly, in the “old-domain to new-domain” case, the RewriteRule


considers only the URL information appearing after the domain, and then
redirects any matching patterns to the new domain, which must be declared
in full because it is different than the local (assumed) domain.

Not sure if that made sense or not. You could also think of it this way: in

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

either case, the RewriteRule does not match against any part of the root
domain name (e.g., http://domain.tld) because it is assumed that it will
be included in the URL. When the matched string is then redirected within
the same domain, the domain remains assumed and does not need to be
declared explicitly in the target string.

However, when the matched string needs redirected to a different domain


(as in the old-to-new redirect), the domain obviously cannot be assumed
and thus must be declared.

I hope that sheds some light on the issue. Thanks for asking a question that
I am sure other people have scratched their heads about.

August Klotz #52


You may also use RedirectMatch to redirect an old domain to a new
domain:

RedirectMatch 301 ^(.*)$ http://new-domain.tld/$1

This will redirect everything on the old domain to the same directory on
new-domain.tld.

Fakhri #53
Hi,

I have a domain name with hosting on one server, but all the content of the
website is hosted on a different server including HTML pages with images,
javascripts and css.

What I want to achieve is that when anyone browse my website for e.g:
www.abc.com it should fetch the entire content from that other website.

Remember that all the pages that could be requested doesn’t physically
exists. It only contains the template. When the request arrive the other
website is running an engine which reads the request and generates the
page on the fly reading just the template.

I have achieved the redirection using the following rewrite rule:

RewriteRule ^(.*)$ http://www.domain.tld/render.php?$1 [P]

But the problem is with images, javascript and css because of their relative
paths.

I can give the absolute paths but I don’t want any user to know about it.

I hope I have cleared what I wanted to.

Can you help me in this regard? Its really urgent!

Ray #54
Any help with this one appreciated (if it’s possible), I can see a soltion
abobe.

I have a domain that I don’t use i.e. domain2.com. I use lots of subdomains
at this domain e.g. abc.domain2.com.

I would like to redirect any visitors to domain2.com to mymainwebsite.com


but leave the sub-domians fucntionling as they do now.

Sony Lazarus #55


There is an excellent htaccess guide called Stupid htaccess tricks ,Thanks for
the doc

Erin #56
Hi! Thanks for this great resource. I’m having trouble with some code that I

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

copied straight from this page though. I’m referring to the missing images
redirect. I’ve got a directory called “c” full of images. Once a month, these
images are pruned and deleted. I’d like requests for the pruned images to
be directed to another image, but the following code is only producing a 404
error:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule c/.* c/out-of-date-ticker.jpg

What’s wrong here? Thanks!

Perishable #57
Erin,

There are at least two problems with your code. First, because of the !-f in
the second line, the rule will match only against files that do not exist.
Then, the third line is telling Apache to serve the image out-of-date-
ticker.jpg for all file requests, including requests for out-of-date-
ticker.jpg itself. In other words, you are blocking the image you are trying
to serve. There are other subtle inconsistencies as well, but you get the
idea.

There are several ways to fix your code. For example, to retain as much as
possible of the original formula, try something like this:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule c/(.*) http://domain.tld/out-of-date.jpg [R,NC,L]

Here, we have removed the exclamation point (not operator) from the
second line, so that we are looking for any file that does exist. Then, in the
third line, we cleaned up the syntax a little bit and resolved the infinite loop
by placing the out-of-date.jpg image in the parent directory, as specified
via absolute URL. Finally, we added a few useful flags, instructing the server
to issue a redirect, ignore casing, and terminate rewriting, respectively.

I hope this helps. Please let me know if I may be of any further assistance.

DAVID #58
Hi folks,
I hope somebody can help me here.
I have osCommerce website installed in directory /ceske-slovenske-
potraviny/
and because I have two domains .com and .co.uk I wanted to to use
RewriteCond to handle redirect.
So I want all request (even non www) to go to subdirectory of main domain
www.halusky.co.uk/ceske-slovenske-potraviny/

This redirect seem to work okay, but the problem is I want password
protected directory www.halusky.co.uk/ceske-slovenske-potraviny/
/protected/ and this doesnt work when I use this RewriteCond.
When RewriteCond is in place and I try to access protected directory I am
redirected to page about cookies.
I know this is more OsCommerce related problem, but maybe somebody
have any tips.

my htaccess
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^.*$ [NC]
RewriteRule ^(.*)$ http://www.halusky.co.uk/ceske-slovenske-
potraviny/$1 [L,R=301]

Manu #59

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

a fantastic collection of tricks! thank you!

I’ve got a question, too. I wrote a c#-program which connects to several


files in a directory. It provides a user-agent-string, lets say it’s called
‘myProgram’. Now I tried to deny all user-agents but not myProgram. What
I did:
SetEnvIfNoCase User-Agent myProgram AllowedAgent

order allow,deny
allow from env=AllowedAgent
deny from all

Unfortunately not only IE & FF are getting a 403, also my program gets this.
What could I do?

Yokhannan #60
Hello,

I have got a website with a RSS Feed. There is this one website totally
abusing my rss feed. I only know the domain name of the website, and
cannot figure out the ipaddress of the hosting server.

How can I go about denying access to my rss feed for this one website??

Thanks man… killer documentation here!

Perishable #61
Yokhannan,

I recently published an article that covers a nearly identical topic..

With just a few modifications of the code presented in that article, we arrive
at this:

# block scum domain from accessing feed


RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_REFERER} ^http://(www\.)?bad-domain\.com/.*$
[NC]
RewriteCond %{REQUEST_URI} /your-feed\.xml$
RewriteRule .* - [F]

This code will block anything at bad-domain.com from your accessing your-
feed.xml. Simply edit the names/paths to match your setup and you should
be good to go.

Sam #62
I always found apache config files and mod_rewrite to be voodoo magic. I
am glad you try to make it makes sense to folk who do not understand
regular expressions.

I am really looking for a way to use mod_rewrite to map various html


pages to long folder names so it looks like I have a clear directory structure.

http://mydomain.org/services.htm maps to
http://mydomain.org/services. A link under services.htm should map to
http://mydomain.org/services/linkname

frann #63
This is brilliant! Thanks.

I have been trying your code for sending hotlinkers a different image, but
they just get a blank, instead of my specially crafted image - which is fine!

Is there a way to prevent people rightclicking on an image and downloading


it like that (in htaccess)?

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

frann #64
I need to allow montastic.com to monitor the sites, is there a way to modify
this:

RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK|OPTIONS|HEAD)$ [NC]


RewriteRule ^.*$ - [F]

so as to allow just them access?

(How did you learn all this stuff… it’s almost like you WROTE htaccess)

Perishable #65
frann,

It is not possible to control browser behavior such as image downloading


using htaccess. htaccess directives operate at the server level and do not
affect content once it is delivered to the browser. Thus, once a browser has
displayed images from a page, those images have already been downloaded
and are available to anyone who knows how to get them. Of course, there
are myriad JavaScript methods of disabling right-clicking, source-code
viewing, and things of that nature if you are serious about trying to prevent
people from copying your images.

As for your second question, you may need to employ an alternate approach
to your strategy. Something along the lines of:

<LimitExcept GET POST>


   order deny,allow
   deny from all
   allow from montastic.com
</LimitExcept>

..which should allow normal browsing activity for everyone while preventing
tracing, tracking, etc. from everyone except montastic.com.

Regards,
Jeff

frann #66
Well. All I can say is your genius astounds me.

Claire #67
another round of applause from me.

My question is i have a folder that needs to be 777 (agggh) but will only be
used as an upload place by the server. I know i can prevent naughty stuff
being run in the folder, but can i actually restrict access to the
server(localhost) only?!

i think like this

   order deny,allow
   deny from all
   allow from localhost

Perishable #68
Claire,

I have seen localhost used in such fashion, but cannot verify that it
actually works. However, because localhost resolves to 127.0.0.1, you
should be able to use something like this:

<Limit GET POST>

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

     order deny,allow
     deny from all
     allow from 127.0.0.1
</Limit>

sarang #69
I have a folder named ‘pdf’ in the root directory containing pdf and zip files.
This folder also has index file which has links to pdf and zip files. i want
users to download these files through index file only. that means any direct
calls to pdf and zip files should be redirected to the index file contained in
the same folder.

how should i do it! please help.

Perishable #70
sarang,

This sounds a lot like hotlink prevention. Try using something like this:

# prevent direct access to pdf and zip files


RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://domain.tld/path/files/.*$
[NC]
RewriteRule .*\.(pdf|zip)$ http://domain.tld/path/files/index.php
[R,NC,L]

Place that code in the directory containing your .pdf and .zip files. Edit the
domain and path in the last two lines to suit your needs. Upload, test, and
done. You may also want to disable directory browsing in general by placing
this code in the root htaccess file of your site:

# disable directory browsing


Options All -Indexes

No editing is required for this last bit of code. Simply upload and enjoy!

John Skillings #71


Hi,

I am tyring to create a user friendly URL and need help with the rewrite.

The URL is of the pattern:

http://www.example.com/www/en/index.php

I would like to shorten this to:

http://www.example.com/index.php

I tried the following rewrite command:

RewriteEngine On
RewriteRule ^/www/en/$ /$1/ [L]

This has no effect. Any help in fixing the expression is appreciated.

Thanks.

John

Nathan #72
My site serves some large files. Some of the download clients make multiple
simultaneous requests, each request is for a different segment of the same
file. Is it possible to tell Apache to honor only one request (per file) from
each client?

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

frann #73
I’ve been finding occasional 404s from user access codes which are banned
in my .htaccess files. As, in the past, I also found ips that were banned
getting through I googled for bypass .htaccess and found this:
http://www.verisign.com/security…advisories/2003/97.html

As i use php mainly, i am a bit worried by this. Have you any ideas?

Perishable #74
frann,

Thanks for the heads up.. I have heard a little about this elsewhere and will
definitely look into it. If/when I find anything useful or relevant I will post it
as soon as possible.

frann #75
Ok, I’ve decided to tackle this in php, so I have written this include to put in
all my pages. I had already stuck all the ips and uas in mySQL tables,
because I have too many htaccess files to deal with manually (it just got
boring). The 2 tables are just lists of ips or uas with the date added.

Hopefully, i haven’t made some stupid mistake or other. If I stop seeing


these intruders, I will deem it a success…

Perishable #76
frann,

Well, now you have me intrigued!

I wouldn’t suppose you would be willing to share your code with the rest of
us, would you?

In any case, I read through the article you mentioned, and am planning a
short post on the issue as soon as time allows. There is a vulnerability, but
it is quite limited and easily prevented.

( Share that code! )

frann #77
Yeah, silly me…

$sitename = "mydomain.com";
$dbServer = "mysql.{$sitename}";
$dbUser = "reader";
$dbPass = "password";
$dbName = "ignorecentral";
$link = mysql_connect("$dbServer", "$dbUser", "$dbPass") or
die("Could not connect");
//print "Connected successfully";
mysql_select_db("$dbName") or die("Could not select database");
//print "Database selected successfully";
$query = "select ip from ipbanlist";
$result1 = mysql_query($query);
$allbanned = mysql_num_rows($result1);
$visitor_ip = $_SERVER['REMOTE_ADDR'];
for ($j=0;$j&lt;$allbanned;$j++) {
   $row = mysql_fetch_array($result1);
   if($visitor_ip == $row['ip']) {
      header("Status: 401 Unauthorized");
      exit;
   }
}
$query = "select userAgent from uabanlist";
$result2 = mysql_query($query);

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

$allbanned = mysql_num_rows($result2);
$visitor_ua = $_SERVER['HTTP_USER_AGENT'];
for ($j=0;$j<$allbanned;$j++) {
   $row = mysql_fetch_array($result2);
   $check_ua = stripslashes($row['userAgent']);
   if(substr($visitor_ua,0,strlen($check_ua)) == $check_ua) {
      header("Status: 401 Unauthorized");
      exit;
   }
}

(note: this should work for the libwww for example)

Perishable #78
Ahh, very nice.. I now see what you mean! If you don’t mind, I am going to
consolidate the three different code chunks into a single comment
(WordPress can get pretty hungry sometimes), so that others may learn
from it as well. Thanks for sharing ;)

Bohackl #79
Great stuff… The htaccess examples are worth their weight in gold. I’ve got
this one bookmarked.

Bohack

Doug #80
This is an amazing post…I can’t tell you how many people I send here to
learn from your examples. One htaccess solution I’ve created is combining
the SSL forced acceptance, a(n) HTTP authentication, protect from
spam/scraping and altering files.

This is what I’m using so far:

AuthType Basic
AuthName "password"
AuthUserFile "/home/usernamehere/.htpasswds/public_html/passwd"
require valid-user
DirectoryIndex "/mywiki/index.php"
Options All -Indexes
# permanently redirect from www domain to non-www domain
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{HTTP_HOST} ^www\.domainname\.com$ [NC]
RewriteRule ^(.*)$ https://domainname.com/$1 [R=301,L]

# require SSL
SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "domainname.com"
ErrorDocument 403 https://domainname.com
# require SSL without mod_ssl
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

# Ultimate htaccess Blacklist 2 from Perishable Press


# Deny domain access to spammers and other scumbags
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} ADSARobot|ah-ha... #I used all
the ones you layed out! again, amazing!
RewriteRule ^.* - [F,L]

# deny all .htaccess, .DS_Store $hî†é and ._* (resource fork)


files
<Files ~ "^\.([Hh][Tt]|[Dd][Ss]_[Ss]|[_])">

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

 Order allow,deny
 Deny from all
 Satisfy All
</Files>

# deny access to all .log and .comment files


<Files ~ "^.*\.([Ll][Oo][Gg]|[cC][oO][mM][mM][eE][nN][tT])">
 Order allow,deny
 Deny from all
 Satisfy All
</Files>

One thing I would love is preventing any hotlinking as well..I tried several
ways but it just shuts the whole site down (something was looping I think).
I imagine the hotlinking might be over kill since you need to authenticate to
get access to anything on the root level….I’d still like to know you thoughts
on that

Any improvements to this would be huge.

Also, have you heard of a way to take the HTTP Authentication values that
were submitted within the popup to be able to pass into/populate inside of a
second login form? I have a LDAP login area and I want to pass the http
authentication values into a second submit form (it’s not me who’s lazy
here, some other people want this ~sigh~)

Any insight of places you think I should investigate further would be really
helpful. Thank you again for everything.

-Doug

bLuefRogX #81
This is actually pretty useful, I wouldn’t quite call this stupid.

http://www.verisign.com/security…advisories/2003/97.html

I do believe this has been resolved in the php5 branch though.

Dave Atkins #82


This post goes into my bookmarks and onto our internal wiki ASAP. Lots of
great info…but I have a question I hope someone can answer:

I am using a password-protected copy of wordpress as a data entry tool for


our editors, behind a basic authentication password screen:

AuthName AuthorizedUsersOnly
AuthType Basic

require valid-user

However, I would like to expose the RSS feed of the “site” so our editors
can monitor new posts through Google Reader. Is there a way to unprotect
the rss feed so it can be read by Google Reader? The feed looks like it is
just “/?feed=rss2″

I think it might be possible with a Files directive…but that url is not a file…

Andrew #83
I hope I did not miss this.
I would like to make attempts to load a file type (flv) from a certain folder
re-direct the user to an error doc or ugly gif.
But allow the flv to load if requested by another Specific file on the server.
This file is a SWF which will play the flv.

Much appreciated.

David #84
Simply amazing stuff - I cannot thank you enough for the clear, concise

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

information. You really should put a “Donate” button somewhere - I sure


would contribute to this and any future additions. Sincere thanks.

Trackbacks / Pingbacks
1. Fun and functional ways to trick out your htaccess file | 43 Folders

2. warpedvisions.org » Blog Archive » A metric tonne of .htaccess tips

3. links for 2006-11-24 « xtra’s blog

4. A View From Home

5. links for 2006-11-25 | A Whole Lotta Nothing

6. links for 2006-11-25 « Breyten’s Dev Blog

7. pix.l|ne ’s Journal » Blog Archive » Beginners guide to .htaccess file

8. KevinDonahue.com » Blog Archive » links for 2006-11-26

9. SSDD Web Design » Article » Stupid .htaccess Tricks

10. dailywebthing linkport

11. » Blog Archive » links for 2006-11-27

12. Austoon Daily » Stupid htaccess Tricks

13. Maria Langer, the Official Web Site* » links for 2006-12-07

14. Maria Langer, the Official Web Site* » Reorganizing WordPress Categories

15. WordPress Visual QuickStart Guide » Reorganizing WordPress Categories

16. Amanita.net » Blog Archive » links for 2007-01-11

17. Net Crap (11/28) « Musings of a Chicagoan

18. ripp.net

19. .Htaccess Reference | WebGeek

20. How to do “X” using htaccess?

21. Protect your site from spam bots at Michael

22. dev2 - webfejlesztés

23. warpedvisions.org » Blog Archive » Stupid htaccess tricks

24. Password Robot Blog

25. Liens de juillet 2007 .::::::. le blog de SkyMinds

26. Best Apache .htaccess tips, tricks, hacks, and examples.

27. mcdave.net » links for 2007-08-11

28. mod_rewrite and htaccess: Its ALL Here @ Webmaster ToolBox

29. systemBash » .htaccess stupid tips and tricks

30. The magic of htaccess | Rickard Andersson

31. Stupid htaccess Tricks | David Bisset: Web Designer, Coder, Wordpress Guru

32. Yeraze's Domain 2.0 - Neat Tricks with .htaccess

Comments are closed for this post


If you have or need further information, contact me.

Previous post: Information Theme Next post: Preparing for Business

Current projects Featured Friends


Some of my other websites and projects.. Featured at these fine sites.. Through thick and thin..

9rules Network Thane Champie

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]


Stupid htaccess Tricks • Perishable Press

Planet WordPress Chris Coyier

DivineCSS Jacob Gube

More.. More..

Social Media
Some more than others, here are some of my favorites..

Too cool for Flickr..


Latest images from my Perishable photo stream

© 2010 Perishable Press • Sitemap • Site Credits • Website design by Monzilla Media

http://perishablepress.com/press/2006/01/10/stupid-htaccess-tricks/[11/17/2010 4:54:01 PM]

Anda mungkin juga menyukai