How can I protect php execution in specific upload directory?
Mostly, people put .htaccess in upload folder to protect php execution. But someone says it can be replaced by attackers.
So how can I control it from the root .htaccess ?
I tried to put the below codes in root .htaccess but it shows "500 internal sever error" and my website goes down.

<Directory ^public_html/product/uploads>
<Files ^(*.php|*.phps)>
    order deny,allow
    deny from all

Thanks in advance

4 Answers 4


Have you tried using "'s?

<Directory "^public_html/product/uploads">
<Files "^(*.php|*.phps)">
    order deny,allow
    deny from all

This would deny users from accessing PHP files. Alternatively, you can disable the PHP engine for this directory, allow the files to be read. Check out the related question Disable PHP in directory (including all sub-directories) with .htaccess

  • Thanks, I checked with your codes but it doesn't work,I guess it was the sever configuration problem. For now, I just deny php execution from uploads/ folder (not from root folder).Then, I set only read permission for that .htaccess
    – ronaldtgi
    Jan 29, 2015 at 11:16
  • 1
    Files with .php5 extension still execute.
    – ptvty
    Feb 17, 2018 at 11:48

The answer from @Dog-eat-cat-world is a good start but you should avoid using .htaccess all together.

It is a huge performance killer and when using something other than Apache Httpd it might not even be used (like nginx).

It is better (and cleaner) to put this kind of restrictions inside your (virtual-)host config file. Also as for example Drupal recommends here do:

  • turn off any options not needed
  • Override the php handler to something nonexistent.
  • Possibly disable the php engine completely.

Directly from ./sites/default/files/.htacces inside a working drupal 7 setup.

# Turn off all options we don't need.

Options None

Options +FollowSymLinks

# Set the catch-all handler to prevent scripts from being executed.

SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006

# Override the handler again if we're run later in the evaluation list.

SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003

# If we know how to do it safely, disable the PHP engine entirely.

php_flag engine off.

  • 1
    Define "huge performance killer" in the real world. Jul 17, 2017 at 15:31
  • the look up for all those .htacces files can take more than a few seconds, and is done for each directory in use. and is non cachable. So per Directory used per request apache looks for this file (when configured to do so) parses its contents and applies the directives in it. When you put it in the virtual host the file is only parsed once and the result is cached in memory.
    – LvB
    Jul 18, 2017 at 8:16
  • 1
    That's the theory yes, but I have never experienced it taking any noticeable time, and definitely not "a few seconds". Would have to be a very slow server and filesystem for that to happen I would imagine. Jul 19, 2017 at 9:21
  • if you got any .htaccess files the performance hit is allready there (apache checks the file location regardless of if it will use it, this is for performance reasons.). If you disable it like @wireghoul suggests and do that in all configured hosts you will see apache perform much better. Apache does cache its 'result config' for a few seconds each time it does the evaluation but that just hides the issue. My 1 second was a statistic I measured in a load test I did about 10 years ago on apache with 10k concurrent connections. (sadly I could not publish it)
    – LvB
    Jul 19, 2017 at 17:48
  • 10 years ago?! Maybe there's the explanation of our different experiences...! If you run a very high traffic site you might have to worry about .htaccess files but on most sites where traffic volume is low those few extra milliseconds doesn't matter. Of course, if you are able to put it into the host config you can do it, but sometimes it is very inconvenient or even impossible. Jul 20, 2017 at 19:12

All of the other answers are good. I agree with Lawri, you should place the limitation in your VirtualHost section of your Apache configuration and not use .htaccess files as they cause performance hits, makes debugging difficult and can be used to bypass both the proposed solutions. So you will need to add AllowOverride None to your Apache configuration as well. Otherwise an attacker could upload a self contained htaccess webshell.


I use in Centos 6.10 for multiple folders in virtual host .conf definitioin file:

<DirectoryMatch ^/var/www/mysite/htdocs/(nophpexecutefolder1|nophpexecutefolder2)>
       php_admin_value engine Off

However, even though it doesn't parse php code the usual way it still outputs from a .php things such as variable declarations and text when doing echo e.g.


echo "<strong>PHP CODE EXECUTED!!";


echo $a+$b;

The above produces in web browser?

PHP CODE EXECUTED!!"; $a=1; $b=2; echo $a+$b;

This could potentially expose some code to users which isn't ideal.

Therefore, it's probably best to use the above in combination with the following in .htaccess:

<FilesMatch ".*.(php|php3|php4|php5|php6|php7|php8|phps|pl|py|pyc|pyo|jsp|asp|htm|html|shtml|phtml|sh|cgi)$">
 Order Deny,Allow
 Deny from all
  #IPs to allow access to the above extensions in current folder
  # Allow from XXX.XXX.XXX.XXX/32 XXX.XXX.XXX.XXX/32

The above will prevent access to any of the above file extensions but will allow other extensions such as images, css etc. to be accessed the usual way. The error when accessing .php:


You don't have permission to access /nophpexecutefolder1/somefile.php on this server.

You must log in to answer this question.

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