Equivalent of Apache's SetEnv Variable

On czw, sie 05, 2010 at 03:45:09 -0700, Michael S. wrote:

example. That example -may- have just unraveled my whole point of the
discussion, too. It’s late :slight_smile:

Oh, so my patch wouldn’t help you at all for dynamically generated css
files. You’d have to teach your app to send the proper headers itself.

understood. I’d say most of us are using things like try_files and if
(-e $request_filename) type checks already, so nginx is aware of the
files themselves, hence that interesting idea of a try_files $uri
inside of the location for .php files… unless I’m missing something
which is blatantly obvious in the internals of course :slight_smile:

Yes, Nginx is aware of files, of course :slight_smile: but unlike Apache, where
everything must be a file, it prefers operating on URLs and uses files
as late as possible. That’s my understanding of its philosophy, at
least.

Best regards,
Grzegorz N.

On Thu, Aug 05, 2010 at 03:09:14PM +0400, Igor S. wrote:

On Thu, Aug 05, 2010 at 12:53:26PM +0200, Grzegorz N. wrote:

Yes, Nginx is aware of files, of course :slight_smile: but unlike Apache, where
everything must be a file, it prefers operating on URLs and uses files
as late as possible. That’s my understanding of its philosophy, at
least.

I believe NSCA/Apache was being developed primarily as static web server.

I should say “as static/CGI web server”.

So all these , , .htaccess, etc exist.
Then mod_proxy module has been added. In nginx static files processing
is just a part of functionality, so it uses "location"s only (analog of
Apache’s ) to concentrate processing in a single place.


Igor S.
http://sysoev.ru/en/

Slow reply - apologies

See, just checked the wiki. Surely this example allows you to
immediately upload a new file with a .php suffix and exploit the server?
http://wiki.nginx.org/NginxMediaWiki
Mediawiki doesn’t allow that. It filters by an allowed list of
extensions, and .php isn’t among them.

Uh uh. As demonstrated above, you appear to be able to bypass this by
adding /.php to the URL

Lets spell this out. Anyone using these suggested default
configurations is massively vulnerable to injected php scripts. Just
upload an “phpinfo()” script named hello.jpg then browse to
http://url/hello.jpg/.php and watch as your php gets executed

There may be a bunch of ways that this isn’t a vulnerability on all
configurations, but the point is this is a default and a simple scan
of a bunch of nginx machines is going to reveal a high count of machines
vulnerable to injection? Not sure why this isn’t getting more
attention?

Look I’m being a bit subtle about this, but I would have thought this
was an urgent scramble to fix kind of thing?

Of course, if you can also let Nginx provide another ounce of
prevention, then all the better.

This isn’t an nginx “problem”, it’s a configuration problem. “we” (the
wiki) are advising people to incorrectly configure their PHP apps

Unfortunately most PHP applications
expect to be able to run arbitrary PHP scripts from almost any directory
under the sun,

Hmm, I disagree on “most”. The small selection that I use tend to use
only a small number of locations.

In my config I either:

  • Move the data dirs out of the htdocs patch altogether (gallery2 and
    others support this)
  • Configure only certain files or restricted directories to be treated
    as PHP apps
  • Reluctantly I might do the reverse and allow all .php files to be
    treated as PHP, but then add an “if” in the location to prevent the data
    dirs from being scanned. I needed to do this for mediawiki for
    example. Note that this is a tricky config because generally you use a
    regexp location for the .php and so you can’t override it with a
    “location /uploads” since it’s parsed later - instead you need to add an
    “If” into the php location…

or simply
make sure that it’s not possible to upload files ending with .php.

This is a partial solution at best. As shown previously it doesn’t
actually help you for a lot of configuration examples since trivially
appending /.php on the end allows you to get the file to be parsed by
the PHP interpretor under many configurations?

Webapps are often built assuming apache and will ship with a bunch of
.htaccess files that stop the php interpretor running files in that
location, ie the upload files dir will have a .htaccess in it turning
off the php interpretor. Now even under Apache this is hit and miss
because many installations will disable htaccess files for performance
reasons (or not allow all actions from the .htaccess). Of course when
you install your PHP app on nginx I would guess it’s quite normal for
the operator to forget to scan for .htaccess files and translate these
to nginx config rules (not nginx’s fault, this is an app configuration
issue)

No one seems quite as excited about this as I feel? What am I missing?

Ed W

On Thu, Aug 26, 2010 at 4:07 AM, Ed W [email protected] wrote:

 Slow reply - apologies

There is a quick hack, that should work, but does add at least another
stat call or two. Basically it’s one last additional “is this -really-
a file” check. Of course it does require nginx to have filesystem
access (not a remote fastcgi_pass)

It was something along the lines of:

location ~ .php$ {
try_files $uri @404; # have to make a named 404 location then.
fastcgi_pass 127.0.0.1:11000;
}

Or this is probably a bit clearer, but more evil because it uses “if”

location ~ .php$ {
if (!-f $request_filename) { return 404; } # or whatever you want to
return
fastcgi_pass 127.0.0.1:11000;
}

On 8/26/10 7:07 AM, Ed W wrote:

No one seems quite as excited about this as I feel? What am I missing?

What you say is true, that such a file would be parsed as PHP if
requested in that manner but it needs to be uploaded successfully first.
Most modern PHP based galleries will not upload a file ending with
“.jpg” unless it actually is a JPEG. Same with a file misidentified as a
PNG. Try it with a phpinfo script. It won’t upload into apps like
vBulletin or IPB. I can’t speak for a lot of others since I haven’t
tested them.

If an app does upload a misidentified file so easily, then the onus is
on the webmaster to configure nginx correctly or, more simply, to not
use the app or to not allow uploads from untrusted sources. The method
proposed by Mike will work fine for such insecure apps, but the real fix
is to fix the app.

The “try_files” approach will be much more efficient than any “if” will
be if you insist on using an insecure app.


Jim O.

On 27/08/2010 03:20, Jim O. wrote:

into apps like vBulletin or IPB. I can’t speak for a lot of others

I still think you guys aren’t getting the point?

The wiki documents an insecure method of setting up many PHP
applications. It’s almost the number one security vulnerability that
you MUST secure your uploads directory and assuming that the PHP
application can/will do this perfectly is optimistic at best. A little
help from the webserver is your minimum second layer of defence really.
In fact many “secure” PHP applications delegate security of the upload
directory completely to the webserver and ship with .htaccess files to
disable php access…

It’s not about whether you and I can setup a secure nginx setup, it’s
about the wiki encourage perhaps tens of thousands of users to setup
their systems so that they can be trivially broken into. Of course we
can all sit back and call the users who followed “our” instructions
idiots when this turns into a mass epidemic, but in the meantime there
is a huge encouragement to setup a bunch of PHP apps so that they can be
trivially broken into?

You are correct that all kinds of vague ways can defend against various
aspects of this. However, bottom line is that there are few perfect php
applications which perfectly filter uploads. There are a lot of clever
ways to sneak junk past upload filters

Just to knock one final myth on the head. Construct a .jpg file like
this and it appears to me that it will work fine and also slip past many
file filters:

echo -e “\xff\xd8\xff\xe0” > test.jpg

file test.jpg

test.jpg: JPEG image data

php test.jpg

???
hello

The correct solution is to:

  • Enable PHP for the minimum number of file locations possible
  • Treat the upload directory as a special case and disable as much as
    possible there (beware ordering in conf files)
  • If possible use try_files on certain locations to further limit scope
    of attack (may not be possible everywhere)

Why doesn’t anyone think this is a huge accident waiting to blowup?

Ed W