A few days ago, RSnake wrote a blog posting about a Firefox extension called ”XSS Warning“ which was written by Gianni Amato. The idea of the extension is quiet simple because all it does is just analyze the URL ind the URL bar when you start the request. Gianni did all of this with just a few lines of JavaScript code and if you just try out the extension it might seem to really protect you against temporary XSS attacks.
I have two points I’ll write about in this posting, first the problem I see on the side of the users because they do expect something wrong out of installing this extension and after that, I’ll go into the technical stuff and show you why at the moment the level of protection by this extension’s very low.
1.) I really like the idea of a client side protection through the web browser or in this case an additional extension but it will never cover all the security issues we’ve got out there in the Internet. Think about anti-virus software, this kind of software and the companies behind try to make you think, that you’re secure and no virus or worm can do something bad to your computer or your data but we (hopefully) know that this isn’t true, it’s just one additional layer of security but also this layer can be broken completely. What I want to show you is, that it’s good to try defending people but we have to take care that they don’t think that they’re absolutely secure and especially in the case of this “XSS Warning”-Extension a user’s only protected (let’s see later how good this protection is) against temporary XSS but not against the much more dangerous permanent XSS stuff. So we really have to take care on how we bring such protection mechanisms to the people, so that they really know what this piece of software can do for them but they also have to know about it’s limitations.
2.) The problem on the technical side is, that the extension will just analyze the URL for the “<” character which’s used to start a new tag in HTML or also a new scripting tag. The test for this character (sorry I don’t know the name in English
) was done carefully as long as you have one of the most used character set so this is the first point of attack but most of the time an attacker wouldn’t be able to change the used character set so let’s think of a more practicable way of breaking or better say bypassing the “XSS Warning”-Extension. As we already have seen, it just looks for the “<” character, even in Hex or Decimal encoding but it won’t check for any other character. To show you what this means, just have a look at the following examples:
(don’t care about register globals and so on
)
PHP:
<?php
echo("<a href='".$abc."'>LINK");
?>
JSP:
< %= "<a href='"+request.getParameter( "abc" )+"'>LINK" %>
In both of these examples a user can set a link through his request or better be more exact and say through setting the variable “abc”. Of course normally this isn’t the case but in many cases a user input will be echoed somewhere in a link and that’s why it is a good reallife example. Now, what can we do here? We can simply bypass the ”XSS Warning“-Extension
http://localhost/?abc='; onmouseover="alert('XSS');"
style="position:absolute;top:0px;width:100000px;height:1000px;z-index:99999;">
With this example (thanks to Romain Gaucher’s blog posting) we can now execute our XSS and we don’t need any “<” which means that we won’t get any alert by the “XSS Warning”-Extension.
OK we see, that we’re not really secure with this extension but it show us, that people are trying to do something against the XSS problem which I think is good and also important so thanks to Gianni Amato and all the other (web) security researchers and keep up the good work.
I tested XSS Warning extension. Works as advertised. It’s not perfect, but it is a good start. I really hope Gianni Amato will continue with this project.
I have no luck with that “real life” example mentioned. Can’t get it to work. Let’s say I have a site with reflected XSS like this: http://localhost/search.asp=“>alert(123)
How can I replace it with onmouseover example?
In the case I described, the string you have in variable “abc” have to be putted into a Link. Most time you’ll see this behaviour is in the navigation of a page where an argument out of the URL will be added to each link of the navigation, for example if you have language=1 you can put my example into the variable “language”. This wouldn’t work if the argument you send to the server will just be echoed, it’s important that it’s in an already existing tag because else you need to put in there a “< ” yourself and that will be detected by the “XSS Warning”-Extension. Hope you get the point, else just ask again
Hi Sven,
RSnake (who’s a NoScript user) put also a link to NoScript’s new anti-XSS protection ( http://noscript.net/features#xss ), mainly aimed to prevent XSS type 1 (reflected) attacks from subverting the JS blocking whitelist.
I bet you’ll have quite a harder time to break it
Hi Giorgio,
I already have seen, that NoScript now have such a function but for any reason, I never had a XSS alert by the extension. Correct me if I’m wrong but AFAIK the XSS protection should also work if you’ve allowed JavaScript globally, so let’s take the following example:
< ?php
echo $string;
?>
Now I send there a request like:
/?string="><iframe src=http://somewhere.xyz/xss.html>
This is a XSS attack and so from my point of view it should be blocked by the NoScript extension but it wouldn’t. Can you explain my why?
By the way, I’m also a NoScript user and it’s a very cool extension.
PS: Don’t beat me if I’ve misunderstood something
Sven, I’m proud you’re a NoScript user too
As explained in NoScript XSS FAQ — http://noscript.net/faq#xss — NoScript filters suspicious XSS request only if they originate from “untrusted” sites (the whole “unkwown” internet, which cannot execute JavaScript) and are targeted to whitelisted sites.
The point of NoScript is that you should whitelist only sites you trust (never trust a forum, persistent XSS anyone?), and since its XSS filters are effective because they’re also much aggressive (default-deny), it would be counter-productive “crippling” trusted sites preventing them from executing cross-site (hopefully legit) requests and thus inducing users to disable XSS protection or, worse, uninstall NoScript.
The “Allow Scripts Globally” command should be banned, and after all it warns you “danger! danger!” all the time
As you surely understand from my explanation above, if you declare to “trust all the internet”, XSS protection doesn’t apply anymore.
If you want to test it, just go to the last page of the “so it begins” thread on RSnake’s forum — http://sla.ckers.org/forum/read.php?3,44,11050#msg-11050 — and choose any PoC directed to a site in your whitelist (be sure to keep sla.ckers.org out, otherwise it would be an unfiltered trusted->trusted request).
Notice that if you follow a XSS to a site out of your whitelist and then you “Allow” it, NoScript anti-XSS protection immediately kicks-in preventing the obvious “reload exploit”
Hi Giorgio,
thanks for your answer, now I’ve got XSS errors on my screen, what a wonderful world
When I’ve got some time left, perhaps I’ll check out if I can find a way to bypass NoScript but for now, thanks for such a great extension.
Disenchant,
thanx for your explaination. Sadly, I stil can’t manage it to work. I tried your PHP example above and the onmouseover string… it just don’t work. The string was formated like this:
‘; onmouseover=”alert(123);” style=”position:absolute;top:0px;width:100000px;height:1000px;z-index:99999;”>
Hi /nul,
the examples should work. Is it possible that you’ve magic_quotes_gpc active and get something like the following?
<a href='\'; onmouseover=\"alert(\'XSS\');\"
style=\"position:absolute;top:0px;width:100000px;height:1000px;z-index:99999;\">'>LINK
@Sven,
thanks for your tests. I have added a new analysis of the URL for the “ ‘ ” character, but not is possible filter all special characters beacuse we risk the false positives.
XSS Warning is young, it must still grow
@/nul,
you it tries within php.ini
@Giorgio
I’m trying the new version of NoScript.
Disenchant,
I disabled the magic_quotes_gpc. Tested it on IE7 / FF2, but still no luck… it drives me nuts
Here’s the screenshot:
http://shrani.si/files/untitledzmm7.png
The code is copy/paste from your PHP example, the onmouseover string is from your example too…
Do you move your mouse over your browser render screen?
Do you move your mouse over your browser render screen?
Maybe your semi-column is too much after the first quote in your string..
@ /nul
Just for you, I’ve set up an example
http://tinyurl.com/33mv7q
The script on the server’s the following (can’t set the magic_quotes_gpc there to off so I had to add the stripslashes)
< ?php
echo("<a href='".stripslashes($abc)."'>LINK</a>");
?>
@ Gianni
Cool, I’ll try it out as soon as possible, I really like to test new countermeasures against XSS attacks
Disenchant,
thank your very much for your kind help. Yep, your link sure works
I had no doubt that your example wouldn’t work. I just couldn’t reproduce it.
Copy/pasted your code (again) on my box, copy/pasted the onmouseover string… I didn’t work! What the hell? The machine used was Windows box. Then I tried Linux box… and it worked
So, it may sound strange, but I can’t reproduce it on Windows box, while it works like cham on Linux. Nevermind, it works.
Thanx again Disenchant.
/nul,
no problem, also if you have any further questions don’t hesitate to ask
I’ve just tried out the example also under Windows and it worked for me without any problems in Firefox 2.0.0.3.
First off, I would like to apologize for offtopic I started…
I did more tests, trying to reproduce issue on Windows box. I had no luck… While it works OK on Linux, I can’t make it to work on Windows. There must be some reason. Probably an configuration/version issue.
I checked phpinfo() on my Linux (magic_quotes_gpc was ON) and I configured the same preferences in my Win box php.ini. Loaded the site, loaded the onmouseover string… nope. I used the stripslashes() version of the example. Tried in IE7 and FF 2.0.0.3. The site just don’t render. I mean, there is a “LINK”, but the site doesn’t have the right dimensions (width:100000px;height:1000px). When I move the mouse over, nothing happen. As I said, it works on Linux.
I came to conclusion (probably wrong
) that it must be because of PHP versions. On my Linux box there’s a version 4.4.4 while on Windows there’s a 5.2.1.
Or maybe there are some other settings in php.ini that are crucial to make this work?
Hi /nul,
the version of PHP can’t be the problem because PHP is only what’s on the server side and because we’re talking here about a client side attack, the HTML source is what matters. Just watch the HTML source of the site I’ve set up here http://tinyurl.com/33mv7q and compare it to yours so you’ll see were the difference is