tags:

views:

234

answers:

9

Maybe I am being a bit paranoid, but as I am re-writing a contact module, the following question came to mind:

Can I use unfiltered input in php's native functions?

It is easy to sanitize stuff to put in a database, output to the screen, etc. but I was wondering if for example the following statement could be dangerous:

    if (file_exists($_POST['brochure'])) {
        // do some stuff
    }

If someone somehow managed to post to that page, could the above code be exploited?

The above code is just an example, I can think of other functions I use when processing a form.

Edit: Thanks everybody, the file_exists in the example is actually part of a sanitation function but when cleaning up, php functions are being used so it is rapidly becoming a chicken and egg story: To use functions, I have to clean up, but to clean up I have to use functions.

Anyway, I have got some fresh ideas now.

+4  A: 

could 'brochure' = '../../../../.htaccess'

that's an interesting question.

Apache on my computer is set to deny listing or viewing .ht* and .ini and .php.inc files, but you have me worried now.

42
php has access to a lot more files than apache. Stopping apache from displaying .ht* and .ini files wont stop php from reading them.
Marius
@Marius this is very true.
Unkwntech
excellent point gents. I'm learning shocking things here :)
42
+10  A: 

Yep. All I'd have to do is post "/etc/passwd", or "includes/dbconnection.php" (or anything) to your page, and depending on what //do some stuff actually is, I could possibly delete, modify or read sensitive information. The file_exists function itself won't do anything you wouldn't expect, but you can expect malicious users exploiting your logic.

Always sanitise your user input. Always. If you're expecting to only grab files from one particular folder, don't allow .. or / in the input

nickf
+6  A: 

PHP's builtins won't do "unexpected" things on bad input (eg, file_exists("foo; rm -r /") will say "no, the file 'foo; rm -r /' doesn't exist")... And if they do, that's a bug you can file against Zend.

Of course, this doesn't stop people from exploiting your code (eg, file_exists("../hidden/shell.php")), so you should still (actually, you should always) be careful when passing user-supplied input around.

David Wolever
+8  A: 

By itself, that looks reasonably safe, but it could be used to reveal information. It could allow an attack to check for the presence (or absence) of particular files (e.g. /etc/passwd, /proc/*, etc).

So in this example, you should ensure that $_POST['brochure'] is sanitised first to only accept inputs that match potentially valid file names. Drop any input that contains .., or that starts with a /.

Other functions could have potentially much worse side effects...

Alnitak
What's your method of keeping an always current list of valid file names? manually updated hash/array of all possibilities that you check against? if not $brochure is in $directoryHash?
42
no need for a list, normally just a regexp that filters out the obvious ways that an attacker could access some file that's outside the directory where files intended to be served are stored.
Alnitak
+2  A: 

You should really be in the habit of filtering all input, but you might like to check out http://www.hardened-php.net/ which distributes a hardening patch and 'Suhosin', which is in many binary distributions by default (OpenSUSE, Mandriva and Debian/Ubuntu)

Paul Dixon
Thanks, I already have that patch installed.
jeroen
+2  A: 

The fact that you have to ask is your answer. It's not safe.

file_exists() is not as bad as others, but if you don't see the source code for the function you're passing data to, and know how it handles user input, then you're taking a chance.

It's not a good idea to pass unfiltered user data into any php filesystem command. The key with security is that you never allow input to context switch. In this case, your minimum sanitization should be removing path characters.

Always assume a hostile user and the worst they could possibly do if they saw your source code.

danieltalsky
A: 

Over the years security vulnerabilities have been found in the source of PHP itself, such that functions were suseptable to bufferoverflow style attacks Suhosin is/was a project that patched PHP to remove some of the risk.

Alan Storm
A: 

What happens with the database string is that it could be retrieved and used somewhere that has a vulnerability. For the answer to your question, think about removing the step where you store the string and then retrieve it. You use it right away, and you have the same risks.

gbarry
Thanks, but I´m afraid I don´t have a clue what you´re talking about. What do you mean?
jeroen
What I mean is that using unfiltered user input is always considered dangerous in php. It's just too easy for someone to insert something that's an exploit. You seemed to be familiar with this in regard to databases; I was pointing out that the problem isn't in that but with the user input itself.
gbarry
+1  A: 

I wouldn't trust those functions at all.

This may definitively sound strikingly, however when I closely watch the people and their C code quality in the commits, reverts, etc. over the last eight years, I'm just in constant fear.

mark