Can anyone guide me on how I can limit the file types that can be downloaded in Apache from a directory listing?
I have some Directory definitions in httpd.conf, like the following:
<Directory "/var/www/data01">
Options Indexes FollowSymLinks
Require all granted
AllowOverride none
</Directory>
What I want to let the user do is list ALL of the files in every folder but only download files with specific extensions (e.g. *.txt)
I've tried this:
<Directory "/var/www/data01">
Options Indexes FollowSymLinks
IndexOptions ShowForbidden
Require all granted
AllowOverride all
order allow,deny
<FilesMatch "\.txt$">
order deny,allow
allow from all
</FilesMatch>
</Directory>
But this gives me a 'You do not have permission to access' error when I browse a folder.
Best Answer
You could use mod_rewrite. Try the following:
This prevents access (403 Forbidden) if not requesting a
.txt
file or the bare directory (required in order to get the directory listing). TheNS
(nosubreq
) flag is required in order to skip internal subrequests. When the directory listing is generated, an internal subrequest appears to be triggered for each file in the directory. So, without theNS
flag, the directory listing is ultimately blocked.You shouldn't really mix
Require
(Apache 2.4+) andOrder allow,deny
(Apache 2.2). The Apache 2.2 directives are only available for backwards compatibility. You should be usingRequire
on Apache 2.4+. Incidentally, these two directives do the opposite... the first one allows access, then the second denies it. The net result is that access is denied (but that's not because of the order of these directives, but because "denying" access wins).UPDATE: To get this to work on subdirectories as well then change the
RewriteRule
directive to:The
RewriteCond
(condition) directive ensures that the following directive only applies to actual files (ignoring directories). This allows us to simplify theRewriteRule
pattern slightly since we don't need to explicitly check for the base directory.