Question

For some application, users are able to upload their own files. Since this can be very large files, they are allowed to upload them via their own FTP client.

Of course I wouldn't like them to upload some PHP files with which they can access all other files on the server. One of the ways I want to prevent this behavior is by denying access to specific file types (like php, rb, py, etc.) only in these folders.

I have found ways to deny access to folders, to files, to files in folders, but nothing about file types in folders.

I tried combining what I've found, like:

<Files ~ "\.inc$">
Order allow,deny
Deny from all
</Files>

changing to

<Files uploads/ "\.inc$">
Order allow,deny
Deny from all
</Files>

or alternative ways

RewriteRule ^(\.php) - [F,L,NC] 

to

RewriteRule ^(uploads/\.php) - [F,L,NC]

However, I can't find out what syntax I should use.

So, for example, I could have the following (basic example):

/index.php
/uploads/
  hack.php
  hack.rb
  hack.py
  pony.jpg

I want hack.php/rb/py to be unavailable, but everything else to be available. What syntax should I use?

Was it helpful?

Solution

The FilesMatch directive works purely on filenames. It doesn't look at the path portion at all.

If you want to specify directives in the root .htaccess file to control a subdirectory, you can use mod_rewrite.

Try this:

RewriteRule ^uploads/.*\.(php|rb|py)$ - [F,L,NC]

The above will block any filename ending in .php or .rb or .py in the /uploads directory or its subdirectories. For example, it will block:

  • /uploads/something.php
  • /uploads/something/more.php

Note that there is no leading slash in the rewrite rule. The path that you need to use in the directive will be different depending on where it's placed. The above directive, if placed in the document root's .htaccess file, will work for files in a directory called uploads that is directly beneath document root.

While the above answers your question, it would be safer to allow only specific files rather than trying to block files. Often a server will execute files with extensions other than the ones you've listed.

You could do something like this:

RewriteCond %{REQUEST_URI} ^/uploads [NC]
RewriteCond %{REQUEST_URI} !\.(jpe?g|png|gif)$ [NC]
RewriteRule .* - [F,L]

With the above, if the request URI begins with /uploads but does not end with one of the specified extensions, then it is forbidden. You can change the extensions to whatever suits your needs. But that way, you can permit extensions as needed rather than finding out too late that you missed blocking one.

This rule (from your question)

RewriteRule ^(uploads/\.php) - [F,L,NC]

will block

  • /uploads/.php
  • /uploads/.phpmore

but it does not allow for anything between the directory name and the file extension.

If you are going to use rewirte rules, you might want to learn more about regexp. I often refer to www.regular-expressions.info when I need to look up something.

OTHER TIPS

You can put a .htaccess in the upload directory. The directives will then apply to this directory and the directories below only. See How directives are applied for details.

So, a .htaccess with FilesMatch can restrict access for files matching *.inc, *.php and so on, when it is in the public directory

<FilesMatch "\.(?:inc|php|py|rb)$">
Order allow,deny
Deny from all
</FilesMatch>

You can use The following easiest and one liner solution to deny access to certen file types:

RedirectMatch 403 ^/folder/.+\.(png|gif|js)$

This will return a 403 Access forbidden error for clients if they try to access /folder/file.extension .

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top