The <Location>
(and <LocationMatch>
) directives match against the URL-path, not strictly the filesystem path, so it's not necessarily recommended to use this to control access anyway (in the server config).
If you have access to the server config then you would just use the relevant <Directory>
container.
Without using a .htaccess
in the subdirectory you could use mod_setenvif to set an environment variable conditionally based on the requested URL and then block based on this env var.
For example:
SetEnvIf Request_URI "^/subdirectory/.+\.php$" BLOCK
<IfModule !mod_authz_core.c>
Order deny,allow
Deny from env=BLOCK
</IfModule>
<IfModule mod_authz_core.c>
<RequireAll>
Require all granted
Require not env BLOCK
</RequireAll>
</IfModule>
I reversed the Order
directive (Apache 2.2), otherwise, without an additional Allow
directive, everything would be blocked.
The Apache 2.4 directives need to be inside a <RequireAll>
container, first granting all access (otherwise everything is blocked) and then denying access conditionally when the BLOCK
env var is set. You can't have a negated Require
directive - in an implied <RequireAny>
container - as it won't have any effect (in fact, this results in a 500 error).
Note that this blocks URLs, not strictly "files". It blocks requests that look like .php
files in /subdirectory
- regardless of whether they actually exist as physical files.
Alternatively, you could use mod_rewrite (Apache 2.2 and 2.4) at the top of your root .htaccess
file:
RewriteEngine On
RewriteRule ^subdirectory/.+\.php$ - [F]
This simply blocks (403 Forbidden) all URLs that end in .php
that are in the requested /subdirectory
. If you specifically need to only return a 403 for URLs that map to real files then you can include an additional condition (although this is probably unnecessarily wasteful):
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^subdirectory/.+\.php$ - [F]
Change F
to R=404
if you wanted to return a 404 instead.