# PHP files being downloaded on condition

**URL:** <https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193>\
**Category:** NGINX\
**Created:** [August 2, 2011, 8:05am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193 "2011-08-02T08:05:11Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubstep](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/cdc98d/32.png) [@dubstep](https://www.ruby-forum.com/u/dubstep)\
**Post date:** [August 2, 2011, 8:05am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/1 "2011-08-02T08:05:11Z")

</div>

Hello, guys,

Another Apache convert here. My 3rd day with nginx and loving it.

I have a nginx + php-fpm setup. The problem is that nginx downloads the  
PHP scripts without being parsed instead of passing them to php-fpm - so  
far I have discovered that happening only with Chrome’s 14.0.835  
(64bit), otherwise it works just fine; there is no difference whether  
php-fpm is running or not, so I think it is safe to assume that the  
scripts are not being passed to the backend at all. The relevant  
(hopefuly configuration):

```
    location ~ \/[0-9a-zA-Z]+\.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED

```

$document\_root$fastcgi\_script\_name;  
fastcgi\_param SCRIPT\_FILENAME  
$document\_root$fastcgi\_script\_name;  
fastcgi\_intercept\_errors on;  
if ($uri ~\*  
/(images?|system|download|upload|cache|logs?)/(.\*/)?[0-9a-z]+.php$)  
{  
return 404;  
}  
fastcgi\_pass php-fpm;  
}

```
    location /url/ {
            alias /dir/url/;
            index index.php;

            if ($request_uri ~* \.(ico|css|js|gif|jpe?g|png)$) {
                    expires 30d;
                    break;
            }
            if (-f $request_filename) {
                    break;
            }}

```

Any ideas? How can I prevent such things from happening, providing some  
failsafe, disallowing php files’ download? I have so far come out with  
that, protecting only possible configuration files:

```
    location ~ (/\.|.*conf.*\.php) {
        deny all;
    }

```

But I would like a more generic approach, if possible.

Thank you for your time.

Posted at Nginx Forum:

> **[PHP files being downloaded on condition](https://forum.nginx.org/read.php?2,213229,213229#msg-213229)**
>
> Hello, guys, Another Apache convert here. My 3rd day with nginx and loving it. I have a nginx + php-fpm setup. The problem is that nginx downloads the PHP scripts without being parsed instead of passing them to php-fpm - so far I have discovered that...

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 2, 2011, 8:26am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/2 "2011-08-02T08:26:14Z")

</div>

On Tue, Aug 02, 2011 at 01:35:41AM -0400, Samael wrote:

> (hopefuly configuration):  
> fastcgi\_param SCRIPT\_FILENAME  
> location /url/ {
> 
> Any ideas? How can I prevent such things from happening, providing some  
> failsafe, disallowing php files’ download? I have so far come out with  
> that, protecting only possible configuration files:
> 
> ```
> location ~ (/\.|.*conf.*\.php) {
> deny all;
> }
> 
> ```
> 
> But I would like a more generic approach, if possible.

Your .htaccess style configuration is not easy to understand.  
Could you describe in words what you want to get ?

–  
Igor S.

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 2, 2011, 8:27am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/3 "2011-08-02T08:27:28Z")

</div>

On Tue, Aug 2, 2011 at 12:35 PM, Samael [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> (hopefuly configuration):

have you tried clearing your browser’s cache?

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 3, 2011, 9:33pm UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/4 "2011-08-03T21:33:34Z")

</div>

On Tue, Aug 02, 2011 at 03:28:16AM -0400, Samael wrote:

> {  
> configuration files from being exposed.
> 
> I hope I didn’t do anything stupid, I’m open to suggestions 🙂
> 
> Edho, thank you for your advice, clearing the browser cache did the  
> trick, but still - I’d like to prevent that happening again by somehow  
> guarding the PHP scripts from being downloaded because of some  
> configuration error, for example.

Any “if ($uri ~\* …)” construction means that it should  
be replaced with “locaiton ~\* …”.

As to regex locations I personally prefer to not use them at all  
for several reasons, and to use only prefix locations, such as

location /download/ {  
location /scripts/ {

I consider regex location usage only in legacy setups.  
There are several ways to prevent execution of PHP in unexpected  
places. 1st, the best one is to use prefix location:

location /scripts/ {  
fastcgi\_pass …  
fastcgi\_param SCRIPT\_FILENAME /www/site$uri;  
}

then anything such /images, /download, /upload will be hanlded in other  
locations as static files.

If you have to use regex, then you can set SCRIPT\_FILENAME to directory  
separated from user uploadable content:

location ~ .php$ {  
fastcgi\_pass …  
fastcgi\_param SCRIPT\_FILENAME /www/site/scripts$uri;  
}

If /download, /upload, etc will be in /www/site/download/,  
/www/site/upload, then it will be impossible to execute  
/www/site/upload/hack.php, since nginx will use  
/www/site/scripts/upload/hach.php instead.

The 3rd way, if you can not place scripts in separate directory, you  
should proper order of regex locations:

location ~ ^/download {  
root /www/site;  
}

location ~ ^/upload {  
root /www/site;  
}

location ~ .php$ {  
root /www/site;  
}

–  
Igor S.

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 4, 2011, 10:34am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/5 "2011-08-04T10:34:16Z")

</div>

Thanks for the suggestions, I will check how can I improve my  
configuration upon them. Unfortunately, they seem to be less generic (ie  
including specific paths) and so promote the probability of making  
errors.

I’m wondering about the regex usage in location though - this is one of  
the things I like very much about nginx. Can you please elaborate the  
reasons for avoiding them?

Posted at Nginx Forum:

> **[Re: PHP files being downloaded on condition](https://forum.nginx.org/read.php?2,213229,213375#msg-213375)**
>
> Hello, guys, Another Apache convert here. My 3rd day with nginx and loving it. I have a nginx + php-fpm setup. The problem is that nginx downloads the PHP scripts without being parsed instead of passing them to php-fpm - so far I have discovered that...

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 2, 2011, 9:28am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/6 "2011-08-02T09:28:36Z")

</div>

Igor, to cut things short - I’d like to either pass the PHP scripts’  
execution to the fcgi processes or prevent them from being downloaded.

In addition, I tried to prevent PHP scripts in common  
webserver-writeable directories (of course, this list will be extended)  
from being executed in order not to allow user-provided PHP files to be  
passed to php-fpm:

if ($uri ~\*  
/(images?|system|download|upload|cache|logs?)/(.\*/)?[0-9a-z]+.php$)  
{  
return 404;  
}

I set this rule: “location ~ /[0-9a-zA-Z]+.php$” in order to evaluate  
only PHP files with alphanumeric names as these are the only one valid  
from my perspective. Of course the rule may be improved (not allowing a  
script beginning with a number to be evaluated), but I don’t think that  
this is necessary at this point.

“location ~ (/.|._conf._.php)” - in order to prevent hidden and  
configuration files from being exposed.

I hope I didn’t do anything stupid, I’m open to suggestions 🙂

Edho, thank you for your advice, clearing the browser cache did the  
trick, but still - I’d like to prevent that happening again by somehow  
guarding the PHP scripts from being downloaded because of some  
configuration error, for example.

Posted at Nginx Forum:

> **[Re: PHP files being downloaded on condition](https://forum.nginx.org/read.php?2,213229,213236#msg-213236)**
>
> Hello, guys, Another Apache convert here. My 3rd day with nginx and loving it. I have a nginx + php-fpm setup. The problem is that nginx downloads the PHP scripts without being parsed instead of passing them to php-fpm - so far I have discovered that...

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 12, 2011, 8:29pm UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/7 "2011-08-12T20:29:23Z")

</div>

Thank you for your advices and your insight, Igor, I’ve adjusted my  
configuration file accordingly, feels much better now. It is stupid, but  
the truth is that I didn’t know that it was possible to use nested  
locations.

Спасибо!

Posted at Nginx Forum:

> **[Re: PHP files being downloaded on condition](https://forum.nginx.org/read.php?2,213229,213747#msg-213747)**
>
> Hello, guys, Another Apache convert here. My 3rd day with nginx and loving it. I have a nginx + php-fpm setup. The problem is that nginx downloads the PHP scripts without being parsed instead of passing them to php-fpm - so far I have discovered that...

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 4, 2011, 12:26pm UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/8 "2011-08-04T12:26:54Z")

</div>

On Thu, Aug 04, 2011 at 04:33:30AM -0400, Samael wrote:

> Thanks for the suggestions, I will check how can I improve my  
> configuration upon them. Unfortunately, they seem to be less generic (ie  
> including specific paths) and so promote the probability of making  
> errors.
> 
> I’m wondering about the regex usage in location though - this is one of  
> the things I like very much about nginx. Can you please elaborate the  
> reasons for avoiding them?

The difference is how nginx processes location.

If you use only prefix or exact locations, then nginx looks up  
the longest match nevertheless of order of locations in configuration  
file.  
This allows you to have hundreds or thousands locations without worrying  
how a new location will affect the existant configuration.

Regex locations depend on order, so during adding a new location  
you have to look though whole configuration to see if the new location  
will affect it.

A man thinks usually that he creates a small configuration with regexes  
and it will work always fine. But configuration usually grows eventually  
and at some point it become a difficult task to add new locations.

Rewrite rules aggravate this more.

–  
Igor S.

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 14, 2011, 12:24am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/9 "2011-08-14T00:24:19Z")

</div>

12.08.2011, 11:28, “Samael” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) ():

> Thank you for your advices and your insight, Igor, I’ve adjusted my  
> configuration file accordingly, feels much better now. It is stupid, but  
> the truth is that I didn’t know that it was possible to use nested  
> locations.
> 
> !

We are working on comprehensive English documentation, including user  
guides and reference.

–  
Igor S.

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 14, 2011, 8:29am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/10 "2011-08-14T08:29:59Z")

</div>

On 2011年08月14日 12:25, Samael wrote:

> [mailman.nginx.org archive](http://mailman.nginx.org/mailman/listinfo/nginx)  
> Good,it will help many people.

–  
Best regards,  
Sharl.Jimh.Tsin (From China _Obviously Taiwan INCLUDED_)

Using Gmail? Please read this important notice:  
[Gmail — Free Software Foundation — Working together for free software](http://www.fsf.org/campaigns/jstrap/gmail?10073).

---

<div class="post-metadata">

**Author:** ![Samael](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/b5ac83/32.png) [@Samael](https://www.ruby-forum.com/u/Samael)\
**Post date:** [August 14, 2011, 6:26am UTC](https://www.ruby-forum.com/t/php-files-being-downloaded-on-condition/210193/11 "2011-08-14T06:26:27Z")

</div>

Well, fortunately, I can read Russian pretty much without problems as I  
studied it for years 🙂

I could even help with the translation, if I may.

Posted at Nginx Forum:

> **[Re: PHP files being downloaded on condition](https://forum.nginx.org/read.php?2,213229,213771#msg-213771)**
>
> Hello, guys, Another Apache convert here. My 3rd day with nginx and loving it. I have a nginx + php-fpm setup. The problem is that nginx downloads the PHP scripts without being parsed instead of passing them to php-fpm - so far I have discovered that...
