3
votes

I'm trying to understand with a short test example how the order deny,allow statements reacts looking to what I've read untill now.

I have the following site structure for testing :

/index.htm
/.htaccess (1)
/subfolder/index.htm
/subfolder/.htaccess (2)

.htaccess (1)

order deny,allow  
allow from all

subfolder/.htaccess (2)

order deny,allow  
deny from all

No matter the order I use for allow,deny / deny,allow (and all 4 possible combinations) in the 2 .htaccess files, I'm never allowed to access the subfolder/index.htm.

As far as I've understood, there is at least one combination where the root allow from all wins on the subfolder deny from all, so I don't understand why I can't succeed doing this on that so simple example.

Can you explain why and what's happening ?

2

2 Answers

6
votes

The Order Directive

The rules order deny,allow and order allow,deny define in which order the deny from and allow from directives are processed. All allow and deny rules are processed, with the final relevant rule overriding any previous rules. See the Order Directive section of the mod_authz_host module documentation for confirmation.

Note that all Allow and Deny directives are processed, unlike a typical firewall, where only the first match is used. The last match is effective (also unlike a typical firewall). Additionally, the order in which lines appear in the configuration files is not significant -- all Allow lines are processed as one group, all Deny lines are considered as another, and the default state is considered by itself.

For example, if we process the deny rules before the allow rules, we can effectively creating a whitelist of allowed IP addresses.

order deny,allow
deny from all
allow from 127.0.0.1

Conversely, in the following example, we process the allow rules, before the deny rules, for a blacklist of denied IP addresses.

order allow,deny
allow from all
deny from 127.0.0.1


Inheritance

Subdirectories will inherit the rules of parent directories, unless they declare their own rules. If a subdirectory uses either an order directive or an allow/deny directive, the rules from the parent are not inherited. See Bug 52406 which refers to the Merging of configuration sections section of this document, for confirmation of this behavior.

For modules that don't implement any merging logic, such as mod_access_compat, the behavior in later sections depends on whether the later section has any directives from the module. The configuration is inherited until a change is made, at which point the configuration is replaced and not merged.

Simple Test

You can also do this simple test to confirm this behavior.

Put the following lines in the parent directory .htaccess.

order deny,allow  
deny from all

And any or all of the following lines in the child directory .htaccess.

order deny,allow  
deny from 0.0.0.0

You will see the the child directory is now publicly accessible, even though the parent directory contains deny from all and the child directory has no allow from directives.


Conclusion

Based on the documentation and experimentation, it seems that it is impossible for a parent directory to override a child director's directives in any way.

3
votes

UPDATE

Using deny, allow directives is deprecated since Apache 2.4 as mentioned here.
So now the right directive that allow all access would be

Require all granted

And to be able to revoke access to a given IP

Require all granted
Require not ip 10.345.67.892