17 December 2021
The mod_rewrite module lets you manipulate URLs. Among others, you can use this to deny access to a page.
Rewrite rules have a condition and rule. The condition defines what needs to be matched, and the rule tells Apache what it should do if a match is found. Both let you use regular expressions.
For instance, let’s say you want to deny access to a contact form at example.com/contact. To do so you can use a rule like this:
RewriteEngine On RewriteCond %{REQUEST_URI} "^/contact" [NC] RewriteRule "^.*$" - [F,L]
The first line enables rewriting – if you forget this line nothing is rewritten. Next is the condition. In the above example I match any URL that starts with with the string /contact (the caret symbol (^
) denotes the start of the string). The NC
flag at the end is used to ignore the case. So, the condition matches /contact, /cOnTaCT and any other weird cases.
The rewrite rule starts with a pattern. Here, the pattern is not important – we just want to deny access to the contact form. The pattern ^.*$
matches any string, which is exactly what we want. The F
flag throws a “forbidden” error, and L
tells Apache to stop processing rules.
You always need to think carefully about the rewrite condition. The above rule matches any URL starting with /contact. That is not necessarily what you want, as there may be other pages that start with the string. For instance, the rule also blocks a URL like /contact-your-mp:
$ curl -IL example.com/contact HTTP/1.1 403 Forbidden ... $ curl -IL example.com/contact-your-mp HTTP/1.1 403 Forbidden ...
To uniquely match /contact you need to use the dollar sign to mark the end of the string. In addition, you may need to match both /contact and /contact/ (note the trailing stroke in the second string). You can do the latter by adding /?
. The question mark matches the preceding character zero or one times. So, it tells Apache that there may or may not be a trailing stroke.
RewriteEngine On RewriteCond %{REQUEST_URI} "^/contact/?$" [NC] RewriteRule "^.*$" - [F,L]
Now, the contact form is blocked but the page about contacting your MP can still be accessed:
$ curl -IL example.com/contact HTTP/1.1 403 Forbidden ... $ curl -IL example.com/contact/ HTTP/1.1 403 Forbidden ... $ curl -IL example.com/contact-your-mp HTTP/1.1 200 OK ...