Search code examples
apachemod-rewriteurl-rewritinghttp-status-code-403whitelist

Apache RewriteRule to only allow whitelist URLs


I have three different categories of URLs. Each category has a specific set of URLs I want to allow and everything else should be forbidden. This is to lock my site down.

These are the categories and the regular expressions I came up with. I'm using Apache 2.4.

First category:

http://example.org/foo
http://example.org/foo/bar
http://example.org/user
^/foo(/bar)?|user$

Second category:

http://example.org/baz/1?foo=bar
^/baz/[0-9]+\?foo=bar$

Third category:

http://example.org/search?bar=baz
^/search\?bar=baz$

Here are the rewrite rules I came up with based on the above:

RewriteEngine On

# Category 1
RewriteCond %{REQUEST_URI} !^/foo(/bar)?|user$ [NC]
RewriteRule ^(.*)$ - [F]

# Category 2
RewriteCond %{REQUEST_URI} !^/baz/[0-9]+$ [NC]
RewriteCond %{QUERY_STRING} !^foo=bar$
RewriteRule ^(.*)$ - [F]

# Category 3
RewriteCond %{REQUEST_URI} !^/search$ [NC]
RewriteCond %{QUERY_STRING} !^b=bar$
RewriteRule ^(.*)$ - [F,L]

The regular expressions look fine to me but as I was testing them at http://htaccess.madewithlove.be/, I noticed that the URL http://example.org/foo will be forbidden at the expression for Category 2. I understand why this happens but I'm not sure how to resolve this. I might be missing something here, can someone tell me how I should fix this?


Solution

  • You should define the white list first, and then restrict/forbid everything else:

    RewriteEngine On
    
    RewriteRule ^(?:foo(?:/bar)?|user)/?$ - [L]
    
    RewriteCond %{QUERY_STRING} ^foo=bar$
    RewriteRule ^baz/\d+$ - [L]
    
    RewriteCond %{QUERY_STRING} ^b=bar$
    RewriteRule ^search$ - [L]
    
    RewriteRule ^ - [F,L]