1

I'd like to configure httpd.conf to deny files that match either of the following:

  1. A directory that starts with . or _
  2. A file that starts with . or _, but does not match __\w+__\.\w+

For example:

/_private/anything       ->  deny (rule 1)
/_private/__init__.py    ->  deny (rule 1)
/_private/_private.txt   ->  deny (rule 1+2)

/public/_private.txt     ->  deny (rule 2)
/public/__private.txt    ->  deny (rule 2)
/public/__public__.txt   ->  allow 

I've been working with <Directory ~ "..."> and <Files ~ "..."> as well as RewriteRule, but haven't been able to get it working just right.

Suggestions much appreciated!

Thanks!


Update: in response to CK:

<Directory "/var/www/html">
    Order allow,deny
    Allow from all
</Directory>

Update 2: Does anyone know why this directive is matching and denying a url like /_test.php, when it is clearly not a "directory" ? (I removed ALL <Files> sections except the .htaccess one.)

<Directory ~ "/[._]">
    Order allow,deny
    Deny from all
</Directory>
1
  • What is your current config? What permissions are on <Directory />?
    – CK.
    Aug 3, 2009 at 23:30

3 Answers 3

1

EDIT: from comment reply original post wasn't quite right - below is new Rewrite rule set:

RewriteRule /\..+ - [F]
RewriteCond %{REQUEST_URI} ^/[^_]+/__\w+__\.\w+$ [NC]
RewriteRule ^ - [S=1]
RewriteRule /_.+ - [F]

Order is important here: - forbid anything starting with period (.) first - its a "global" rule with no special case. - the special case of \w+.\w+ must be allowed through next S=1 skips the next rule being - forbid anything starting with underscore (_)

2
  • Hey, that's really close. But it's running into the same problem I was having... /_sam/__foo__.txt is allowed. My wheels are turning, however, and I think this is the right approach. Maybe I should wait until morning :)
    – gahooa
    Aug 4, 2009 at 2:58
  • Edited post with working version for ya Aug 4, 2009 at 3:57
0

It sounds like you are looking for "DirectoryMatch and FileMatch.

From the apache httpd website. http://httpd.apache.org/docs/2.0/mod/core.html#directorymatch

< DirectoryMatch> and < /DirectoryMatch> are used to enclose a group of directives which will apply only to the named directory and sub-directories of that directory, the same as . However, it takes as an argument a regular expression.

http://httpd.apache.org/docs/2.0/mod/core.html#filesmatch

The < FilesMatch> directive limits the scope of the enclosed directives by filename, just as the < Files> directive does. However, it accepts a regular expression.

2
  • As I pointed out in my post, I am using <Directory ~ "..."> which, according to the apache docs, are exactly the same as <DirectoryMatch ...>.
    – gahooa
    Aug 4, 2009 at 2:43
  • The way you were describing the issue looked as if you wanted regex matching instead of directives that only understand shell type wildcard globing. Aug 6, 2009 at 4:15
0

as with most things like this, the order of rules is crucial.

the best rule of thumb, IMO, is to put the special-case exceptions first and then the general case rule, like so:

  1. allow files that match (^|/)__\w+__.\w+$
  2. deny files or directories that match (^|/)[._]

if the order were reversed from the above, then the file-match exception would never even be reached, so wouldn't have any effect.

BTW, why have such silly rules? why not just put public files in one directory and private files in another? why have private files like '_private.txt' in a directory called /public? why make your public file and directory names so annoyingly similar to your private names? it would make more sense to do things in a more convenient, sensible fashion - sometimes the best answer is DDTT - "Don't Do That, Then".

3
  • Hi Craig. I believe your suggested rule order would allow /_hidden/__init__.php -- is that true? Regarding the BTW, I appreciate you taking the time to write that, but can assure you that there is a bigger picture that I did not take up room in the post to explain. 99% of our non-http accessible files are completely outside the DocumentRoot, but there are some specific exception (with very good cause) that live inside the document root. Either they are directory level PHP or Python runtime configuration files. Calling this silly would be the same as calling apache's .htaccess silly.
    – gahooa
    Aug 4, 2009 at 2:50
  • re: /_hidden_/__init__.php - yes, it would. that's one of the problems with having such similar patterns for your private and public files. you've got three basic options: 1. construct the regex to exclude each private directory, 2. construct it to include each public directory. both of these are potentially never-ending, so the best is option 3. work out some other file/directory naming scheme so that you can have a simple regex that matches all files you want to block while not matching any you want to allow. that's why i called it silly...this is a DDTT problem.
    – cas
    Aug 4, 2009 at 3:01
  • also, add another rule (before the first one) that blocks directories matching (^|/)[._].*/
    – cas
    Aug 4, 2009 at 3:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .