Forum Moderators: phranque
I'm trying to create an .htaccess file that could be distributed as part of a PHP-based web application. I would like this file to be as much location-independent as possible as I cannot assume any particular location, this webapp would be installed in.
My .htaccess file is supposed to enforce the following simple rules:
1. Access is allowed to a handlful of PHP files in the top directory.
2. Access to all other files and subdirectories is banned.
3. Default Index is set to main.php, so that people could run the app via [myserver.com...] or [myserver.com...] (note traling slash) without specifying the php file directly.
A brute force approach to such configuration resulted in the following file:
DirectoryIndex list.php<Files *>
Order deny,allow
Deny from All
</Files>
<FilesMatch "^$">
Order allow,deny
Allow from All
</FilesMatch>
<FilesMatch "^myapp$">
Order allow,deny
Allow from All
</FilesMatch>
<Files *.php>
Order allow,deny
Allow from All
</Files>
The two [u]FilesMatch[/u] rules are introduced to make the configuration handle requests for [myserver.com...] or [myserver.com...] gracefully. Without them the damn thing would reject such request (even though requests for the index file mentioned explicitly via [myserver.com...] did work).
What bothers me is the fact that now my .htaccess is way too coupled with the directory name. Could anyone suggest a better way to enforce the rules above without doing such tricks?
Thanks in advance.
Welcome to WebmasterWorld!
Hmmm... I'm not sure I understand your concern completely. Among other things, I'm not sure which names you are using in your post for files and which are for directories. A few notes:
<Files> and <FilesMatch> are directory-insensitive; The test applies only to the filename, not a full pathname.
<FilesMatch> uses regular expressions, so the construct "<Filesmatch (^$¦^myapp$)>" would be valid, saving you a repeated <Filesmatch> section. (You will have to replace the broken pipe "¦" character with a solid pipe before use; Posting on this board modifies that pipe character.)
We've had discussions here before that lead me to believe that only one <Order> directive should be present in an .htaccess file. Otherwise, unexpected results can follow.
Set it up with one Order directive and a global Deny from All, then create exceptions within the <FilesMatch> containers.
You can place .htaccess code in the directory along with your files, and that code will only affect that directory and its subdirectories.
Taking the above into consideration, perhaps you can provide a few more details...
Jim
I'm sorry if I am not clear. What I mean is the following structure:
myapp/
- main.php
- another.php
- foo.php
- .htaccess
- mysecretfile.dta
- private_notes.txt
- doc/
----- README.txt
----- .svn/
---------- entries
Given this structure, I would like to ensure that only a handful of files are visible, while other files AND directories are not. Furthermore, I would like to make main.php a default index.
Below are several scenarios with desired outcomes:
1. [mysite.com...] --> main.php
2. [mysite.com...] --> main.php
3. [mysite.com...] --> main.php
4. [mysite.com...] --> foo.php
5. [mysite.com...] --> ERROR
6. [mysite.com...] --> ERROR
7. [mysite.com...] --> ERROR
The point here is that I want to make visible as little as possible because things happen and I can mistakenly leave some important file or directory around. Or, I could screw up and forget to upload main.php (in which case I'd rather have the user get an error instead of the directory index).
With the configuration mentioned above, I am almost there. The only culprit is the handling of the translation of the "application directory" URL into the default index (scenarios ##1,2). Looks like File rules are preventing me from doing so. :-(
Maybe there is a simpler way of achieving the objectives I mentioned?
Thanks in advance,
-- Sasha
Even when I add DirectoryIndex main.php it would still prohibit me from accessing the URL without the last file component (doesn't matter whether it is with a trailing slash or without it). The scenarios ## 1,2 from the list above don't work.
So far, the configuration in my original message is the best I've got, even though it's long and it does depend upon the directory name where it is placed... :-(
-- Sasha
Order Deny,Allow
Deny from All
<FilesMatch "^$¦myapp$¦(myapp¦main¦foo)\.php$">
Allow from All
</FilesMatch>
Jim
My issue with this is that the original requirements (which I consider to be common sense) lead to a really non-obvious regular expression after some trial and error. Worse, the result is coupled with the deployment location name.
All of this could be avoided if Apache first applied the index URL production rules (producing an [mysite.com...] as a resulting URL for scenarios 1,2) and then the access restrictions.
Interestingly, not too many people ask the same question around the net. Maybe I'm just too paranoid...
In any case - thank you very much, Jim, for your help.
-- Sasha
Jim