Case-Insensitive RedirectMatch

.htaccess made easy

Cool trick that you may not have known about.. it’s possible to get case-insensitive matching with the powerful RedirectMatch directive. Normally, you would just write your redirect as something like this:

RedirectMatch 301 /phpMyAdmin

This works great, but it’s case-sensitive. You could just match the all-lowercase version, but there are some phrases — such as “phpMyAdmin” — that really benefit from going the case-insensitive route. Those familiar with Apache might be screaming, “just use a rewrite rule!” Something like this will certainly get you there:

<IfModule mod_rewrite.c>
 RewriteCond %{REQUEST_URI} /phpMyAdmin [NC]
 RewriteRule .* [R=301,L] 

Notice the [NC] flag? That tells Apache to ignore casing for the pattern match. This works great, but there are situations where you would rather just keep it simple with good ‘ol RedirectMatch. When? Let me give you an example with the recent WordPress add-on for the 5G Blacklist, which originally looked like this:

# 5G WP
RedirectMatch 403 /\$\&
RedirectMatch 403 /\.(bash|git|hg|log|svn|swp|tar)
RedirectMatch 403 /(1|contact|i|index1|iprober|phpinfo|phpspy|product|signup|t|test|timthumb|tz|visit|webshell|wp-signup).php
RedirectMatch 403 /(author-panel|class|database|manage|phpMyAdmin|register|submit-articles|system|usage|webmaster)/?$
RedirectMatch 403 /(=|_mm|cgi|cvs|dbscripts|jsp|rnd|userfiles)

Simple and effective, made super lightweight and awesome mainly because of the flexible RedirectMatch directive. But notice the “phpMyAdmin” in the penultimate directive — as Andy W reminds us:

Your WP blacklist checks for “phpMyAdmin”. As I understand it RedirectMatch is case sensitive so it wouldn’t block “phpmyadmin” (all lowercase) which I recollect seeing on old logs for my site.

Pattern-matching with case-insensitivity increases the scope of your .htaccess redirect rules. For the RedirectMatch directive, here’s how to do it..

Case-Insensitive RedirectMatch

Fortunately, Apache makes it easy to declare case-insensitivity with RedirectMatch. Simply precede the pattern with “(?i)” (without the quotes). Returning to our initial example, we can get case-insensitivity like so:

RedirectMatch 301 (?i)/phpMyAdmin

That’s all you need to match all the crazy variations for requests such as phpMyAdmin:

  • phpMYadmin
  • PHPmyAdmin
  • phpmyadmin
  • PHPMyAdmin
  • phpMyAdmin

And here is the 5G WP add-on, now with case-insensitivity:

RedirectMatch 403 /\$\&
RedirectMatch 403 (?i)/\.(bash|git|hg|log|svn|swp|tar)
RedirectMatch 403 (?i)/(1|contact|i|index1|iprober|phpinfo|phpspy|product|signup|t|test|timthumb|tz|visit|webshell|wp-signup).php
RedirectMatch 403 (?i)/(author-panel|class|database|manage|phpMyAdmin|register|submit-articles|system|usage|webmaster)/?$
RedirectMatch 403 (?i)/(=|_mm|cgi|cvs|dbscripts|jsp|rnd|userfiles)

When it comes to redirecting most requests, its all lowercase anyway. Or you can use RewriteRule to establish case-insensitivity. But for some situations, it’s good to know that you can also roll with RedirectMatch by simply adding the (?i) to the rule.