Main
Use SSL

XSS passable through htmlentities()

18 May 2008


I used to think that using htmlentites() with ENT_QUOTES is a pretty good "universal" protection against cross site scripting. I used it in all of my projects, and basically relied on it completely. Whenever I got any user input, I passed it through this filter and felt completely safe to use the returned value anywhere in the HTML output. Apparently, this was nothing but a false sense of security.

I can see why I missed it, and that's because the "vulnerability" is pretty obscure, none the less it's there - and I bet many sites can be affected.

Take a look at this code:
<?php
	$filtered = htmlentities($_GET["arg"], ENT_QUOTES);
	echo $filtered;
?>


This is completely fine, and it will always work, providing good security. The problem arises when you try to do something a little more "advanced" with the filtered result. For example:

<?php
	echo "<body onload=\"alert('$filtered')\">Hmm</body>";
?>


If you can see what's the problem with this code right away, than good for you. I didn't, and it took me a little by surprise to see that my filter has completely no effect here.

Just try this input:
?arg=lol'); alert('xss


With Magic Quotes off (and it's already off by default since PHP 6), this results in XSS.

What really happens here, is that HTML entities inside URLs, Event handlers (onload for example), or any other HTML tag properties- are being "read" by browsers as the values they represent. So &#039; becomes ', and that's what the script interpreter sees. This effectively cancels out the effect of my filtering script.

The source of the XSS'd HTML will look like this:
<body onload="alert('lol&#039;); alert(&#039;xss')">Hmm</body>


On first glance you may think that this shouldn't work, but it does. Actually, HTML entities are meant to do that. There is no browser bug or something, only a matter of this feature being slightly hard to grasp.

Also, you can argue that the code I've shown above would be rarely used, and you are right. Yet, look at this code:
<a href="javascript:comments(18)">Comments</a>


This code is taken from this very page. The only thing that saves me from XSS here, is that the ID of the comment is an integer (I cast it that way) and that I don't show the "Comments" link in case the post with the specified ID doesn't exist (I don't show anything, actually).

I bet many web applications use something like this. I can also bet that not many developers are aware of the issue, and think (as I did) that their "universal" HTML filters are truly universal.

Posted by: kGen | In category: XSS | Comments (0)


Restricted ports in Firefox. Why?

16 April 2008


Check this out: http://own-the.net:110 . In Firefox 3 beta 5 (my version, didn't check the rest), it will tell you this:

Port Restricted for Security Reasons

This address uses a network port which is normally used for purposes other than Web browsing. Firefox has canceled the request for your protection.


Now, I don't actually have a POP3 server running on port 110, so obviously Firefox filters these ports without thinking twice. I'm sure you're asking yourself "why?". That was my first response too, until I finally got it.

I'll demonstrate first. I've set up a small HTTP server (just a few lines of Java) on port 1025 (http://own-the.net:1025). All it does, is echo your request. This may seem legit, however, the funny thing is that it's obviously prone to XSS. Worse yet, cookies are sent to a specific domain or sub-domain, but not to a specific port. Thus, the cookies from the "normal" (port 80) site, are also sent to the port 1025 "page".

You can try and send some JS with the request, but I did put some filtering against a real attack.

(Note: In Firefox, requests are automatically URL encoded, so the simplest form of XSS won't work. On IE, however, it will.)

How is this relevant? Well, many servers are running different services on standard ports. FTP, SMTP, POP3, SSH... Lots of them. If any of those services could be tricked into echoing any of the data you send through an HTTP request, you'd be able to perform XSS.

Sadly(?), I didn't actually find a popular service that is prone to this, however, now I can understand the logic behind this annoying port restriction. The aforementioned services shouldn't be responsible for filtering HTML characters, as they are not intended to be used through a browser at all. Consequently, a good browser has to filter these ports out, or else security could be compromised.



Anyway, props to Mozilla for thinking of this in advance.

Posted by: kGen | In category: XSS | Comments (2)