views:

105

answers:

5

I'm new to PHP and I'm following a tutorial here: Link

It's pretty scary that a user can write php code in an input and basically screw your site, right?

Well, now I'm a bit paranoid and I'd rather learn security best practices right off the bat than try to cram them in once I have some habits in me.

Since I'm brand new to PHP (literally picked it up two days ago), I can learn pretty much anything easily without getting confused.

What other way can I prevent shenanigans on my site? :D

+2  A: 

strip_tags is not the best thing to use really, it doesn't protect in all cases.

HTML Purify: http://htmlpurifier.org/

Is a real good option for processing incoming data, however it itself still will not cater for all use cases - but it's definitely a good starting point.

metismo
+1  A: 

strip_tags removes every piece of html. more sophisticated solutions are based on whitelisting (i.e. allowing specific html tags). a good whitelisting library is htmlpurifyer http://htmlpurifier.org/

and of course on the database side of things use functions like mysql_real_escape_string or pg_escape_string

roman
+1  A: 

Well, probably I'm wrong, but... In all literature, I've read, people say It's much better to use htmlspellchars.

Also, rather necessary to cast input data. (for int for example, if you are sure it's user id).

Well, beforehand, when you'll start using database - use mysql_real_escape_string instead of mysql_escape_string to prevent SQL injections (in some old books it's written mysql_escape_string still).

MInner
mysql_escape_string will do in most situations. The php manual says that when binairy data is inserted, mysql_real_escape_string must be used. http://php.net/mysql_real_escape_string
Ikke
+4  A: 

There are several things to keep in mind when developing a PHP application, strip_tags() only helps with one of those. Actually strip_tags(), while effective, might even do more than needed: converting possibly dangerous characters with htmlspecialchars() should even be preferrable, depending on the situation.

Generally it all comes down to two simple rules: filter all input, escape all output. Now you need to understand what exactly constitutes input and output.

Output is easy, everything your application sends to the browser is output, so use htmlspecialchars() or any other escaping function every time you output data you didn't write yourself.

Input is any data not hardcoded in your PHP code: things coming from a form via POST, from a query string via GET, from cookies, all those must be filtered in the most appropriate way depending on your needs. Even data coming from a database should be considered potentially dangerous; especially on shared server you never know if the database was compromised elsewhere in a way that could affect your app too.

There are different ways to filter data: white lists to allow only selected values, validation based on expcted input format and so on. One thing I never suggest is try fixing the data you get from users: have them play by your rules, if you don't get what you expect, reject the request instead of trying to clean it up.

Special attention, if you deal with a database, must be paid to SQL injections: that kind of attack relies on you not properly constructing query strings you send to the database, so that the attacker can forge them trying to execute malicious instruction. You should always use an escaping function such as mysql_real_escape_string() or, better, use prepared statements with the mysqli extension or using PDO.

There's more to say on this topic, but these points should get you started.

HTH

EDIT: to clarify, by "filtering input" I mean decide what's good and what's bad, not modify input data in any way. As I said I'd never modify user data unless it's output to the browser.

kemp
I agree about escaping all output, but not about filtering input. See my response here: http://stackoverflow.com/questions/58694/how-do-i-html-encode-all-the-output-in-a-web-application/60690#60690
JW
Thanks a bunch. Really informative answer and gives me a nudge in just the right direction. Thanks!
Serg
@JW: by filtering I mean deciding what passes and what doesn't, what you say on the response you linked I call escaping.
kemp
@kemp: This might not have been what you meant, but basically I don't think that you should do anything to your input data *en masse*, at the beginning of the app. This leads to catastrophes like PHP's "magic quotes." Of course, you can still do things like validating that the user didn't put a letter in a number field, but that's not really for security purposes.
JW
@JW: never have I said I would do that. In fact I think it was clear that I suggest to *do nothing* to user input, besides reject it if it doesn't match my criteria. I have explicitly said **reject the request instead of trying to clean it up**
kemp
+2  A: 

I have to say that the tutorial you mentioned is a little misleading about security:

It is important to note that you never want to directly work with the $_GET & $_POST values. Always send their value to a local variable, & work with it there. There are several security implications involved with the values when you directly access (or output) $_GET & $_POST.

This is nonsense. Copying a value to a local variable is no more safe than using the $_GET or $_POST variables directly.

In fact, there's nothing inherently unsafe about any data. What matters is what you do with it. There are perfectly legitimate reasons why you might have a $_POST variable that contains ; rm -rf /. This is fine for outputting on an HTML page or storing in a database, for example.

The only time it's unsafe is when you're using a command like system or exec. And that's the time you need to worry about what variables you're using. In this case, you'd probably want to use something like a whitelist, or at least run your values through escapeshellarg.

Similarly with sending queries to databases, sending HTML to browsers, and so on. Escape the data right before you send it somewhere else, using the appropriate escaping method for the destination.

JW
Great! I'm always happy to recieve advice from experts in the field, more so if the information I knew was wrong. Thanks a bunch!
Serg