Repeat After Me: Lack of _Output Encoding_ Causes XSS Vulnerabilities

by Nitesh Dhanjani

I’ve been spending a considerable amount of time auditing web applications, and I’ve come to realize that a large amount of developers do not understand the root cause of Cross Site Scripting (XSS) vulnerabilities. The most common mistake committed by developers (and many security experts, I might add) is to treat XSS as an input validation problem. Therefore, I frequently come across situations where developers fix XSS problems by attempting to filter out meta-characters (<, >, /, ", ', etc). At times, if an exhaustive list of meta-characters is used, it does solve the problem, but it makes the application less friendly to the end user – a large set of characters are deemed forbidden. The correct approach to solving XSS problems is to ensure that every user supplied parameter is HTML Output Encoded (Example: < is replaced with &lt;). Most frameworks (.NET for example) provide API’s that help with HTML encoding, but I have come across instances where such APIs don’t encode certain characters that can lead to XSS when more complicated variants of input are attempted. Therefore, I frequently and highly recommend RSnake’s XSS cheat-sheet to test web based applications and services for XSS vulnerabilities. If you are a web developer or tester, I do recommend that you test your application with the inputs suggested by RSnake to test for XSS issues.


2005-10-27 12:49:30
Built-in with Ruby
Just remember the <%= h( in your .rhtml files, and you're golden. One of the main reasons I'm doing everything in Ruby now.
2005-10-27 13:00:21
Built-in with Struts

2005-10-28 09:24:35
(mostly) Built-in with Perl
The most popular Perl templating engines:


Template Toolkit
[% HTML.escape(foo) %]

2005-10-29 01:08:33
Or, even nicer, you can use the filter syntax in Template Toolkit – either the shortcut version:

[% foo | html %]

Or the more long-winded one:

[% FILTER html ; foo ; END %]

The latter one can be wrapped around arbitrary other template constructs:

[% FILTER html %]This will show up as a literal <br>.[% END %]