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
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>
["<s ", " onmouseover='alert(1)'>", "foobar</s>"]
1 2 3 4
<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> </div>
Nesting of forbidden strings:
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.
- 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.