Here is my response to http://myappsecurity.blogspot.com/2007/01/xss-filter-to-protect-from-xss-attacks.html
This is a good but dangerous effort, the problem is in this example is that Anurag is applying a blackList filter and is only protecting against one case of xss.
Here is the original code code:
String html = request.getParameter(”html”);
out.println(”Here is the filtered output of the html you submitted.”);
out.println(filterRequest(html));
And if I change it to:
String html = “<a href=’” + filterRequest(request.getParameter(”url”)) + “‘>XSS link</a>”;
out.println(”Here is the filtered output of the html you submitted.”);
out.println(html);
which is another example of using user input to create a link
the filter can be easily bypassed.
1) normal request: http://127.0.0.1:8080/servlets-examples/servlet/XSSFilter?url=nextServlet
2) already a type of XSS since this type of redirection should not be allowed: http://127.0.0.1:8080/servlets-examples/servlet/XSSFilter?url=http://www.google.com
3) and here is an XSS 101 payload: http://127.0.0.1:8080/servlets-examples/servlet/XSSFilter?url=nextPage’ onmouseover=’Javascript:alert(document.cookie)
4) or if you want to make sure the user cannot escape: http://127.0.0.1:8080/servlets-examples/servlet/XSSFilter?url=http://www.google.com’ onmouseover=’Javascript:alert(document.cookie)” style=’display:block;position:absolute;left:0;right:0;width:100%25;height:100%25 (thx pdp)
5) note that in example 4) above I could had used ” in the payload since your filter will convert ” to ‘ : http://127.0.0.1:8080/servlets-examples/servlet/XSSFilter?url=nextPage” onmouseover=”Javascript:alert(document.cookie)
6) of course that in this case you could always just do: http://127.0.0.1:8080/servlets-examples/servlet/XSSFilter?url=javascript:alert(document.cookie)
7) and even if you added ‘ to the filter (which might be a problem since in some case you will need to accept it), it wouldn’t cover for this case: String html = “<a href=” + filterRequest(request.getParameter(”url”)) + “>XSS link</a>”;
and lets not forget the XSS caused by double encoding or double decoding in the code
I hope this shows how hard it is to properly mitigate against XSS and that in most cases white listing is the only safe option (and even in those cases XSS might occur).
Another solution that is very rarely talked is to by default encode EVERYthing sent to out.println and force the developers to use strong-typed html classes to create HTML tags.
In the above example your would change
String html = “<a href=’” + filterRequest(request.getParameter(”url”)) + “‘>XSS link</a>”;
out.println(html);
for
safeHtmlBuilder.a html = safeHtmlBuilder.a(request.getParameter(”html”), “XSS link”)
safeHtml.out(html);
Assuming of course that safeHtmlBuilder.a(…) was built properly
Even better than encoding out.println would be to block the developer from invoking out.println directly (which could be enforced via (’Shock Horror!!!’) the Java security manager (or in Partial Trust in .Net)).
We would have a nice solution for XSS (and this is a good example of what I was talking about a while back on using Sandboxes to create environments where these types of vulnerabilities are very hard to exists)
(more…)