views:

169

answers:

4

In PHP, I know that using parameterized queries is the best way to prevent SQL injection.

But what about sanitizing user input that will be used for other purposes, such as:

  • Displaying back to a user (potential cross-site scripting vector)
  • Addressing an email or filling in the message body

Is htmlentities() the best way to sanitize for non-database usage? What is considered to be best practice here?

+5  A: 

In php the best xss filter is:

htmlspecialchars($_POST['param'],ENT_QUOTES);

The reason why you also have to encode quotes is becuase you don't need <> to exploit some xss. for instance this is vulnerable to xss:

print('<A HREF="http://www.xssed.com/'.htmlspecialchars($_REQUEST[xss]).'"&gt;link&lt;/a&gt;');

You don't need <> to execute javascript in this case because you can use onmouseover, here is an example attack:

$_REQUEST[xss]='" onMouseOver="alert(/xss/)"';

the ENT_QUOTES takes care of the double quotes.

E-mail is a bit different, javascript shouldn't be executed by the mail client, and if it is then your site isn't affected due to the Same Origin Policy. But to be on the safe side I would still use htmlspecialchars($var,ENT_QUOTES);. HOWEVER, PHP's mail() function can succumb to a different type of vulnerability, its called CRLF injection. Here is an example vulnerability against PHP-Nuke. If you have a function call like this: mail($fmail, $subject, $message, $header); Then you must make sure that a user cannot inject \r\n into $header.

Vulnerable code:

$header="From: \"$_GET[name]\" <$ymail>\nX-Mailer: PHP";

patched:

$_GET[name]=str_replace(array("\r","\n"),$_GET[name]);
$header="From: \"$_GET[name]\" <$ymail>\nX-Mailer: PHP";
Rook
Is there any automated tests for finding such "holes"?
Kirzilla
Your brain, and your hands. But there are a few if you Google around, the one from http://www.acunetix.com/ is good (but my brain is better) but its not free.
Dr Hydralisk
use the free xss scanner by Acunetix: http://www.acunetix.com/cross-site-scripting/scanner.htm It will test for strange types of xss, like the one in my example.
Rook
Here is another good on I used a long time ago, http://www.websecurify.com/. Its free and cross-platform.
Dr Hydralisk
I agree with you Dr Hydralisk, your brain is better than even Acunetix. As long as you have enough Vespene gas.
Rook
Good test data (no automated test though) could be found on http://ha.ckers.org/xss.html.
MyGGaN
Yes, very original, I don't get that one everyday :D
Dr Hydralisk
@Dr Hydralisk haha, yeah sarcasm aside I agree that manual auditing will without a doubt produce the best results, although I'll hit an app with automation first to pick up the low hanging fruit.
Rook
+1  A: 

Well you can first create rules for certain fields, like email the only thing it should consist of is letters, numbers, @ (at-symbol? what is it really called), and a period, so you cannot form an XSS out of that so no need to waste resources using htmlentities() or htmlspeicalchars().

Dr Hydralisk
+2  A: 

You may also want to checkout HTML Purifier which will strip any dangerous HTML and leave on safe input. You can also create your own rules on what HTML to allow/disallow.

http://htmlpurifier.org/

instigator
Damn, I was about to post that.
Dr Hydralisk
A: 

No,

1) prepared statements are not a solution to SQL injection. In most cases prepared statements implies variable binding and therefore transparent escaping which is an effective way to prevent SQL injection.

2) you DO NOT sanitize input - you sanitize output. By all means validate input (e.g. make sure start date comes before end date), but the repsentation of data should only be changed at the point where it leaves your PHP code. The method for sanitizing data written directly into HTML is different from how you would sanitize data written into a URL is different from how you sanitize data to write it into a javascript string variable is different from how you sanitize data for insertion into an SQL statement is different from how you sanitize data before you send it to modem is...

...what are you going to do? create every possible representation of the data? Create a universal represenation of the data?

http://xkcd.com/327/

C.

symcbean
exactly..........
stereofrog
Way to split some hairs. If you want to suggest methods for sanitizing data to be sent to a modem, that would actually contribute something worthwhile to this discussion.
Nathan Long