During a recent BSides conference the topic of cross server scripting (XSS) with JQuery was discussed. This topic piqued some interest because I was interested in automating unit testing scenarios in JavaScript. What I found was that it was easy to build JS unit tests using JS-Test-Driver test cases around JQuery to test XSS. Here's an example of a JS-test-driver test case:
/**
* appendTest - Unit test for XSS vulnerabilities
*
* Copyright (C) 2012 @rcastellow
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see
*/
appendTest = TestCase("appendTest");
appendTest.prototype.name = "append()";
appendTest.prototype.setUp = function() {
this.testUtils = new TestUtils();
};
appendTest.prototype.testXSS = function() {
/*:DOC htmlTest = <div class="page"><div id="testDiv">abc</div> </div>"
*/
var child = this.testUtils.findFirstChildByTagName(this.htmlTest, 'DIV');
assertNotNull(child);
assertEquals("DIV", child.tagName);
// Add Sample XSS
var xssElement = $(child).append("<script id='bad' src='http://badStuff.js' />");
assertEquals('
xssElement = $(child).append("
assertEquals('
// 3. Test if XSS modified and made the script part of the DOM
if (xssElement.html().trim() != '
jstestdriver.console.log("jQueryXSS", this.name + " has successfully modified the DOM.");
}
};
The results of my unit tests showed me that JQuery is indeed handling some of the more common forms of XSS in more recent versions of JQuery (1.6.2+). jQuery looks for a '<' in its parameters because it is not very common start of a parameter in Javascript, but is very common in html.
The code that handles XSS can be found in the jQuery library in the following lines of code:
// A simple way to check for HTML strings or ID strings
// Prioritize #id over to avoid XSS via location.hash (#9521)
quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
Will it stop all forms of XSS? Probably not, since there are so many ways besides adding a straight html script entry into a jQuery parameter. A future exercise might be to extend my tests to include a wider variety of XSS vectors, many of which can be found here.
No comments:
Post a Comment