Forum Moderators: coopster

Message Too Old, No Replies

PHP Security Issues

Man, am I confused!

         

neophyte

1:46 am on Aug 20, 2007 (gmt 0)

10+ Year Member



Hello All -

I've read a lot on WW about php security issues and techniques in the past week and there's SO much information there about SO many ways to fight security risks that I must admit that I don't know where to start.

I'm mainly concerned with abusive users inputting code in my client's forms which will delete my database or table information, or display links to porno sites or viagra farms or anything else for that matter.

So... what do you protect? ALL text form fields which will be submitted to the DB? Just Textfields?

Not knowing where to start, I'm now validating ALL text fields with regular expressions (like a name field must only contain alpha characters plus a space and hyphen; phone number fields must only contain numeric characters plus a space, hyphen, "+" sign for international numbers, and parens) but is this enough for users bent on injection attacks, etc.? Somehow, I don't think this is nearly enough.

My validation workflow - when a user hits the submit button - is currently -

1. if the text field submitted is REQUIRED and if it is EMPTY then bounce back the form with a warning that this field must be completed
2. if the text field submitted as REQUIRED and if it is NOT EMPTY then validate the POST data against a regular expression for the text field in question (name/phone/email/etc)
3. If the text field submitted IS NOT EMPTY and PASSES the (rather simple) regular expression routine, then submit the information into the database.

But, is that enough? Before the information is inserted into the DB, should all data then be "sanitized" against a number of routines that is written to trap for typical injection type commands?

What would be most helpful to me (and no doubt others) is if there is a some security checklist somewhere on WW that just says:

1. If you've got a text field then you should do this, this, and this before submitting the data to the DB.
2. if you've got a TEXTFIELD then you should do this, this, and this before submitting that information to the DB

... and so on.

Is there such a checklist here? If not, I'm happy to submit one once I know what I'm doing in regards to securing forms appropriately.

All guidance greatly appreciated.

Neophyte

borntobeweb

6:54 am on Aug 20, 2007 (gmt 0)

10+ Year Member



You're on the right track. BTW, phone numbers can also have extensions so you may want to allow for that, and names can contain single-quotes. You also want to check the length of all values (after all single quotes have been escaped) so they don't exceed your DB fields' declared lengths.

SQL injections are side-effects of bugs in the program. One typical bug is to allow non-escaped single-quotes in strings, so someone enters the name "John O'Doe" and your SQL statement becomes

UPDATE mytable SET name = 'John O'Doe' WHERE id = 42;

To prevent this bug pass all input values through mysql_real_escape_string() when adding them to your SQL statements.

The other typical bug is to allow bad numeric values, e.g. someone enters "12;" in a text field and your SQL statement becomes

UPDATE mytable SET num_copies = 12; WHERE id = 42;

To prevent this bug validate the data as you've mentioned, and/or pass all input values intended for numeric fields through intval().

That's on the DB side, on the display side you want to pass everything through htmlspecialchars() or htmlentities() to prevent cross-site scripting (when the user sneaks in <script> or <iframe> tags into text fields). If you want to allow people to add formatting to free-form text, use BB-style [codes] like on this message board and replace them by the appropriate HTML tags after you've passed the text through htmlentities(). Don't forget to do the same for email content that is marked as HTML.

Also search for "php sql injection test cases" to get an idea of what to test for.

neophyte

12:39 am on Aug 21, 2007 (gmt 0)

10+ Year Member



borntobeweb -

Thanks so much for your reply and appreciate your input.

A few questions though:

Currently, before adding any strings to the DB, I've been using addslashes(); it appears that mysql_real_escape_string() does the same job... is this correct?

I don't want ANYONE to supply html in any of my forms so when you spoke of htmlentities() that peaked my interest. However, this function just does a conversion on html-type input. What I'd like is to trap for this type of input and then, if found in any field, it would bounce back to the user with an "HTML characters not allowed" error. To do this, I would need some kind of function that would identify html-type-entities and provide a TRUE/FALSE result... rather than a translation. do you know of any pre-rolled php function that already does this?. then again, I suppose I could just write my own regular expression but I'm not sure if I'd be missing something.

Appreciate your help - and anyone else who would like to weigh in on this.

borntobeweb

2:52 am on Aug 21, 2007 (gmt 0)

10+ Year Member



I believe addslashes() is a generic function to quote problematic characters and mysql_real_escape_string() is specific to MySQL, your choice really.

As far as htmlentities(), it escapes special characters (<, >, ", etc) so they're not interpreted by the browser as HTML code. If you pass all input through that, the user can enter any character they want and it won't mess up your output. For instance, when i find an error in user input, i tend to display an error message and then the form again with the user's input pre-loaded, e.g.

<p>Error: invalid characters in username.</p>
<form>
...
<input type="text" name="username" <?if(isset($_POST['username'])) echo 'value="'.htmlentities($_POST['username']).'"';?> size="20">

Without the call to htmlentities(), if the user enters something like myname"-> then your HTML gets screwed up in the error page.