.htaccess - Make a directory invisible
I have a .htaccess file that currently looks like:
<Files .htaccess> order allow,deny deny from all </Files> Options All -Indexes IndexIgnore * # Respond to /include/ with 404 instead of 403 RewriteEngine On RedirectMatch 404 ^/include(/?|/.*)$
I'm trying to prevent everyone from knowing that /include/ exists, however I've come across an issue.
Although visiting http://www.example.com/include gives a 404, the browser adds an end slash (thus giving http://www.example.com/include/) which shows that the 开发者_如何学Cdirectory is in fact there, but is being disguised. When an actual 404 is visited, an end slash is not appended.
Is there a way to prevent this behavior?
1. You can use DirectorySlash Off
to tell Apache to not to add trailing slash at the end of directories.
2. Why use RewriteEngine On
if you do not actually use rewrite engine (based on the code you have provided)? RedirectMatch
has nothing to do with mod_rewrite
.
3. If you want to use mod_rewrite here, then try this rule -- it will return 404 code for /include
folder (with and without trailing slash) as well as ANY resource inside that file (e.g. /include/main.php
etc).
RewriteEngine On
RewriteRule ^include(/|/.+)?$ - [R=404,L]
Leaking directory existence through dot-files
There are some cases where following lines of code are not enough to hide your directory:
RewriteEngine On
RewriteRule ^include(/|/.+)?$ - [R=404,L]
Those lines won't block requests like include/.php
, include/.ht
, include/.htaccess
(instead you will receive a 403 Forbidden
error which will indicate that the directory include
exists). Instead one would like to forbid access to all dot-files to prevent leaking folder existence (.git
, .php
(just ".php" - without a file name), .htaccess
, ...). (Side note: I guess there might be some issues between the .htaccess file and main Apache config file where you can forbid access to ".ht" files and allow to execute ".php" files - that's why such requests are doing their own thing without beeing simply rewritten to 404 error. Instead they are returning 403 error).
So you can bypass the above rules by sending following requests (you'll receive 403 Forbidden
error):
- http://example.com/include/.php → You'll receive 403 error
- http://example.com/include/.ht → You'll receive 403 error
- http://example.com/include/.htaccess → You'll receive 403 error
You can verify that you'll get 404 Not Found
error if directory doesn't exist:
- http://example.com/DOESNT-EXIST/.php → You'll receive 404 error
- http://example.com/DOESNT-EXIST/.ht → You'll receive 404 error
- http://example.com/DOESNT-EXIST/.htaccess → You'll receive 404 error
Possible Fix
You need to match all the dot-files. So first you disallow access to them (403 error) and then you just rewrite 403 error to 404 error.
Options -Indexes
RewriteEngine On
RewriteRule ^secret.*$ - [R=404,L]
RewriteRule ^404_error$ - [R=404,L]
<FilesMatch "^\\.">
order allow,deny
# 403 error
deny from all
# Rewrite 403 error to 404 error
# Error document must be:
# - "a string with error text" OR
# - an absolute path which starts with "/" OR
# - URL (you'll get a redirect)
ErrorDocument 403 /404_error
</FilesMatch>
These requests are now blocked and you'll get an 404 Not Found
error:
- /secret/treasure.php (all files and directories in that folder)
- /secret
- /secret/
- /secret?42
- /secret/?23
- /secret/.php
- /secret/.htaccess
This is an answer from my similar question: Rewrite requests to directory with htaccess to 404 error
Use a rewrite rule in addition to the RedirectMatch.
精彩评论