views:

145

answers:

3

What are the measures needed to prevent or to stop JavaScript injections from happening in a PHP Web application so that sensitive information is not given out (best-practices in PHP, HTML/XHTML and JavaScript)?

+3  A: 

A good first step is applying the methods listed in the question Gert G linked. This covers in detail the variety of functions that can be used in different situations to cleanse input, including mysql_real_escape_string, htmlentities(), htmlspecialchars(), strip_tags() and addslashes()

A better way, whenever possible, is to avoid inserting user input directly into your database. Employ whitelist input validation: in any situation where you only have a limited range of options, choose from hard-coded values for for insertion, rather than taking the input from any client-side facing form. Basically, this means having only certain values that you accept, instead of trying to eliminate/counter evil/mal-formed/malicious input.

For example: If you have a form with a drop down for items, do not take use the input from this dropdown for insertion. Remember that a malicious client can edit the information sent with the form's submission, even if you think they only have limited options. Instead, have the drop down refer to an index in an array in your server-side code. Then use that array to choose what to insert. This way, even if an attacker tries to send you malicious code, it never actually hits your database.

Obviously, this doesn't work for free-form applications like forums or blogs. For those, you have to fall back on the "first step" techniques. Still, there are a wide range of options that can be improved via whitelist input validation.

You can also use parameterized queries (aka prepared statements with bind variables) for your sql interactions wherever possible. This will tell your database server that all input is simply a value, so it mitigates a lot of the potential problems from injection attacks. In many situations, this can even cover free-form applications.

JGB146
+2  A: 

If your not passing anything that needs to be formated as html then use:

strip_tags() <- Eliminates any suspicious html

and then run the following to clean before saving to the db

mysql_real_escape_string() 

If your ajax is saving user entered html via a textbox or wysiwyg then look into using HTMLPurifier to strip out javascript but allow html tags.

Tim Santeford
+4  A: 

Treat any value you output to html with htmlspecialchars() by default.

Only excuse for not using htmlspecialchars() is when you need to output to html string that itself contains html. In that case you must be sure that this string is from completely safe source. If you don't have such confidence then you must pass it through whitelist html filter that allows only for carefully limited set of tags, attributes, and attribute values. You should be especially careful about attribute values. You should never allow everything to pass as attribute value especially for attributes like src, hef, style.

You should know all places in your webapp where you output anything to html without using htmspeciachars(), be sure that you really need those places and be aware that despite all your confidence those places are potential vulnerabilities.

If you are thinking that this is too much caution: "Why do I need to htmlspecialchar() this variable that of I know it contains just interger and loose all the precious CPU cycles?"

Remember this: You don't know, you only think you know, CPU cycles are cheapest thing in the world and nearly all of them will be wasted by waiting for database or filesystem or even memory access.

Also never use blacklist html filters. Youtube made that mistake and someone suddenly found out that only first <script> is removed and if you enter second one in the comment you can inject any Javascript into visitors browser.

Similarly to avoid SQL Injections treat with mysql_real_escape_string() all values that you glue to SQL query, or better yet use PDO Prepared statements.

Kamil Szot