Re: File Upload Security and chmod

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



So I've been trying to figure out where php uploads files to temporarily
store them before I move them to their permanent storage directory, and I'm
having some difficulties:

-- php_info() says the temporary file upload directory is "/tmp" but I don't
know if that's relative to my root directory or what and can't figure out
from the documentation how that path is displayed.
-- I have tried to call pathinfo() and realpath() on my
$_FILES['name']['tmp_name'] file before it is moved, but neither gives the
full path to the file (which I realized after reading the documentation that
neither is supposed to do).  Any ideas on functions that will give the full
path of the inputted file?  I've been searching the php documentation and
general list but to no avail.  On the plus side, I did get to practice
writing information to a text file, so that was fun :)

Thanks for the tips on the chmod requirements for the get_image_size()
function, I'm all about keep permissions as strict as possible at this
point!

Crap, gotta use my brain, huh?  :)  Seriously, thanks for the overview on
how "security" should be approached and for the advice to not take general
security recommendations at face value but to give them some thought, given
my unique situation.  This is really good for me to learn now, while I'm
still implementing my security rather than later when I might have to redo
everything (or might have a gaping hole based on a poor assumption).  At
least I won't be storing anyone's financial information, so I should only be
a target for people who just want to be mean, but not people who want to get
free stuff from others credit info.

Maybe I should have one of those disclaimers posted on my homepage like the
ones that you see in taxis sometimes: "This driver never carries more than
$20 cash."  -->  "This website never carries anyone's financial
information."  :)

Andy


On 9/26/06, Richard Lynch <ceo@xxxxxxxxx> wrote:

On Mon, September 25, 2006 3:58 pm, Andy Hultgren wrote:
> So I tried to implement the example code given in the php tmpfile()
> documentation and it wouldn't do anything, which suggests that I don't
> have
> access to the /tmp directory.  Also, the FAQ's section on my server's
> website say that /tmp is not shared between the servers.  So, looks
> like
> /tmp option is out...

Did they perhaps give you your own "tmp" directory elsewhere?...

Sometimes you just need to poke at it to figure out where your "tmp"
is, and then you can use the PHP functions that let you specify your
own directory, but not the ones that assume that system /tmp is your
"tmp"

My host has a "tmp" dir I can use, but it ain't /tmp, and PHP
routinely tries to use /tmp with some functions.  Grrrr.

> So, let me see if I understand the situation I'm looking at here:
>
> The bad side:
> -- I don't have any place to put uploaded files outside of my webtree,
> which
> makes it tough to ensure these files cannot be surfed to once they are
> uploaded, and also means I have to do my security checks while the
> files are
> within my webtree and potentially accessible.  (BAD).

Yes.

Though if file uploads are working at all, looking at the $_FILES
array may give you a clue as to a directory that you maybe *can*
access which is your own private "tmp"...

> -- Any php script on my server (created by me or somehow maliciously
> uploaded) can do whatever it wants within my account because all php
> scripts run as me.  (also BAD).

On the plus side, some of the coding gets real simple, since you are
you, and you are never somebody else. :-)

> The good side:
> -- Uploaded files can be chmod so that nobody can read them, then I
> chmod
> them when I need to use them.  This adds a layer of protection for
> completely uploaded files.  I assume this will not help with files
> while
> they are getting their security checks, since PHP has to be able to
> read and
> execute them in order to run the checks (get_image_size, etc.)?

PHP needs to read them for get_image_size, but not execute.

Use minimum force needed.

If you are flipping the chmod around within your scripts, that reduces
your risk to however long the dir remains in its 0777 (or whatever)
state, which is however long your script takes to process whatever it
has to process in that state.

So long exhaustive checks of the validity of a file are "bad" because
that leaves that window open longer, but they're "good" because the
file is then more likely to be kosher.

> -- Since I'm only allowing image uploads, I can strictly filter which
> files
> are allowed to be uploaded (with extension checks and get_image_size).

Extension check is kinda useless...

I can name any file I want with .jpg and upload it.

get_image_size() is good, as it checks the first N bytes -- But
somebody somewhere can construct a worm with the first N bytes that
LOOK like a valid image, to get_image_size()

A human eyeball check would be even better, as then you *know* that a
much larger number of bytes are a valid image.

It could still be "image+worm" with the worm tacked on at the end, and
a valid image at the front, which the browser would probably just go
ahead and display as valid image. :-(

The odds of somebody able to construct a valid-looking image whose
exact byte sequence is also a worm are pretty low, but not
impossible... :-)

> (Plus
> all the stuff talked about in the PHP Security Guide provided by the
> PHP
> Security Consortium for html POSTs, MySQL stuff, cookies, etc. Well,
> all of
> it that I can implement without having access to a directory outside
> of my
> webtree anyway).

Be careful.

It's entirely possible that *some* of the advice would put you at
higher risk with your setup, if their assumption is the "nobody" user
and a directory outside web-tree.

So just because you *CAN* implement your advice in your situation,
won't mean you should.

You're going to have to examine every little thing on a case-by-case
basis with your Security Hat on firmly -- Which means thinking "If I
was Evil, how would I break this?"

> So, given this situation (if I've got it right), I have two questions:
>
> 1) With the above "as is", am I just asking for anyone to come in and
> tear
> my site apart?  I am not an experienced web developer (obviously), but
> I
> love to read.  Is that enough to build a secure site, or am I just way
> in
> over my head?

There's no such thing as "a secure site"...

A secure site is not an off/on switch.  It's more a gradient from
horrible to very strong.

And the act of building a Secure site is not even just a question of
following all the "rules" in http://phpsec.org and so on.

It's a thought process, a living breathing intelligent human actually
*thinking* about what they are doing, and what the Risks are, and what
the Benefits are, and trying to consider every possible angle of every
decision.

Are you building an e-commerce site, right out of the gate, on a
server configured like this?  Bad Idea.

Are you building just a photo upload site?  Probably with a lot of
thought and reading and even more thinking, you can do fine.

You're just going to have to substitute thinking with your own brain
for following the standard advice. :-)

It's certainly going to be better for you in the long run, if nothing
else, as you'll actually THINK more about this stuff than just
following instructions.

> 2) Imaging that I can convince my host to rebuild my site so that I
> have
> access to directories outside of my webtree and can check and save
> uploaded
> files there, does that make the situation substantially better?  Or is
> the
> "PHP running as me" thing enough alone to raise some serious serious
> problems (perhaps less around the image uploading but more around a
> login
> page or something)?

In some ways, having the server running as you is "better" for
security, as any files that you do *NOT* want other users on the same
server to see, you can more easily chmod them to be 0600 or 0400 or
whatever, so only YOU can do anything with them.

So when you read advice to use 0777 you can immediately change that to
0700, because the only access needed is for you, not your group, and
not the "world" of other users on that machine.

The downside is that if somebody does manage to inject any PHP code
(or any other executable code) their injection will be far more
powerful, as it runs as you, a powerful user, and not "nobody" a
powerless users.

So you'll want to be even more careful than usual with the file
uploads to be sure they do not contain any harmful executable
script/code.

--
Like Music?
http://l-i-e.com/artists.htm




[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux