The validator module for Node.js contains functionality meant to filter potential XSS attacks (a filter called xss). In looking at the implementation I discovered several bypasses for this filtering including prior work by other researchers. Although the bypasses I reported have been patched, since my discovery at least one new bypass has been disclosed and remains unpatched.

In general, because the function’s filtering is blacklist-based it is likely that other bypasses will be discovered in the future. Accordingly I would urge Node.js developers not to use the xss filtering function of this package.

What were the bypasses?

All of these were tested in the latest version of Firefox:

Improper parsing of nested tags:

<s <onmouseover="alert(1)"> <s onmouseover="alert(1)">This is a test</s>

Incomplete filtering of javascript: URIs:

<a href="javascriptJ a V a S c R iPt::alert(1)" "<s>">test</a>

Improper handling of arrays passed in (this affects JavaScript because the toString method will automatically join the elements of the array together):

["<s ", " onmouseover='alert(1)'>", "foobar</s>"]

UI Redressing:

<div style="z-index: 9999999; background-color: green; width: 100%; height: 100%">
<h1>You have won</h1>Please click the link and enter your login details:
<a href="http://example.com/">http://good.com</a>

Nesting of forbidden strings:

<scrRedirecRedirect 302t 302ipt type="text/javascript">prompt(1);</scrRedirecRedirect 302t 302ipt>

I also noticed the following comment at the top of the file:

//This module is adapted from the CodeIgniter framework
//The license is available at http://codeigniter.com/

Searching around online, I came across CodeIgniter <= 2.1.1 xss_clean() Cross Site Scripting filter bypass, written by @kkotowicz, which provided me with more working bypasses.


If you are a developer currently using the xss filter function from the validator package, you should consider replacing it with the escape filter function from the same package. This function replaces all instances of angle brackets (<, >), ampersands, and quotation marks, so no HTML tags will be processed.

Note that XSS prevention is not as simple as just escaping those characters. For more information, check out the OWASP XSS Prevention Cheat Sheet.

Disclosure Timeline

  • March 6th, 2013: Initial report to module maintainer via email. Sent proofs of concept, etc.
  • March 10th, 2013: Developer replies, creates public issue on GitHub to track the fix. Promises to resolve the issue “ASAP.”
  • April 17th, 2013, 10:56 PM: Sent pull request which resolves issues.
  • April 17th, 2013, 11:27 PM: Pull request merged by maintainer.
  • April 18th, 2013, 8:31 AM: New version (1.1.0) released containing patch.
  • May 6th, 2013: Additional bypass disclosed publicly by taku0.