Your Apache htaccess ‘Order Deny, Allow’ Not Working?

It’s very easy to make mistakes with the htaccess Order directive, so if it’s not working here’s some tips to fix it (for Apache web servers).

If we get the ‘Deny, Allow’ bit the wrong way round it won’t do what we expect – at best it will do nothing, at worst it denies everybody access to our site. So tread carefully, keep a backup and test after making changes :-)

‘Order’ in htaccess does not work like other kinds of regular expressions (regex).

Key Point 1: Apache always makes THREE passes of the access statements.

It does NOT find the first match and then stop – and that’s what makes things go haywire if we’re not careful.

Why Is It Not Working!?

Here’s a typical “block some IP’s because they keep spamming my WordPress comments” htaccess:-

Order Deny, Allow
Deny from 173.44.37.
Deny from
Allow from all

Looks OK right? It’s allowing everything, but blocking a specific IP address, and an IP range (everything starting with 173.44.37).

Problem is – this does NOT work!

Look closer at that Order statement – Deny first, then Allow.

Key Point 2: This is NOT the order the statements are written. It’s the order in which they will be PROCESSED.

This is what actually happens in this case:-

  1. Apache processes the Deny statements
  2. Then processes the Allow statements
  3. Finally processes anything that doesn’t match either of these

But remember – as I said above, Apache does ALL three of these passes. It does NOT just exit at the first one matched.

So in this example:-

For our regular nice visitor, Apache doesn’t match any denied IP addresses on Pass 1. And then hits the ‘Allow All’ statement on Pass 2. Because we have used ‘All’ here, it matches. There’s no match on Pass 3 because we already matched on Pass 2. So the request is allowed.

If it’s one of our spammers however, Apache does match the IP whilst processing the deny statements. Great, so far so good. But then it processes the Allow statement and is told to ‘Allow All’ – BAM, we just let our spammer back in again!

That’s not what we intended. But the only way we’d know it wasn’t working was if we noticed the spam was still coming from those ‘blocked’ IP addresses!

How To Fix It!

In this case, the fix is as simple as reversing the Order statement. If we simply switch to ‘Order Allow, Deny’ to process the Allow statements first – now things should behave as expected, i.e.

Our spammer arrives. Apache checks for Allow statements, finds an ‘Allow All’ so initially flags the request to be allowed. But then makes a 2nd pass to check the Deny statements. Now it finds a match for the spammer’s IP address, and changes the flag to deny the request instead. The request is blocked.

For our nice visitor, the Allow matches and the Deny doesn’t. The request is Allowed.

Bottom line. The order of ‘Order’ is critical. So be very careful when copying htaccess snippets from other sites, as they may not behave quite as you might expect.

P.S. Don’t forget the 3rd pass entirely. If you’re NOT using an ‘All’ statement somewhere (either in an Allow or Deny) this WILL come into play.

The 3rd case defaults to the SECOND directive – being Allow or Deny depending on what Order you have them.

So for ‘Order Allow, Deny’ where there is no match for either case, the request will default to being Denied. More examples of that another time…

7 Comments to “Your Apache htaccess ‘Order Deny, Allow’ Not Working?”

  1. chrsmyrs 14 December 2012 at 2:28 pm #

    Finally, somebody talking some sense on this subject! Thanks very much!

  2. Tiribulus 23 December 2014 at 5:13 pm #

    I have it correct as per this article and it still does nothing. The spam goes right by into moderation on my blog. Any help with a reason why would be greatly appreciated.

    I have 3 virtual hosts on my server. I have an .htaccess in the root and then one in the root of each vhost identical.

    I put the ones in the vhost dirs after the main one didn’t work. Nothing works, They ignore it and go through. Thanks

    RewriteEngine On
    RewriteBase /
    order allow,deny
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    deny from
    Allow from all

  3. Martin 23 December 2014 at 9:11 pm #

    Darn comment spam 😉

    Your rules look OK. But there could be a conflict elsewhere in the file or in the higher level directory file.

    To make testing easier what I sometimes do is block just my own IP address (it won’t block your FTP access etc, but obviously don’t do this if your only access to htaccess is via WordPress), then you can instantly see what is and isn’t working. Hope that helps you narrow down where the problem lies?

  4. Tiribulus 24 December 2014 at 4:39 am #

    This is actually my own server. That’s all there is in the file and I have them one each in the docroot for each host and then one in the root of the server, identical to this one.

    Thanks again.

  5. Tiribulus 24 December 2014 at 4:48 am #

    i just remoted into my church’s server with RD after putting the IP address in the file. It had no effect.

  6. Martin 24 December 2014 at 4:54 am #

    Hmm – you do have mod_rewrite enabled in Apache?

  7. Tiribulus 24 December 2014 at 12:09 pm #

    Well, this guy’s TEST says it’s working.

    Also if you look under APACHE2HANDLER it says mod_rewrite is loaded. I dunno. I appreciate your time. I am no expert here.

Leave a Reply