| DetailsAffected Software:DojoToolkit Fixed in Version:1.4.2 Issue Type:XSS Original Code: Found Here DescriptionThis week’s vulnerability is a DOM based XSS that could be found in a JavaScript file provided by the DojoToolkit. This JavaScript file was included (via script src) in many pages throughout the DojoToolkit,making those pages vulnerable to XSS. Unlike traditional XSS bugs,server side processing is not required for certain types of DOM based XSS. This is an important concept to understand as some code auditors will skip static pages assuming the attacker will not have the ability to control any values used by the page. The bug starts here: if(window.location.href.indexOf(“?”) >-1){
The JavaScript pulls the address of the loaded page and checks to see if the address contains the “?” character. If the “?” character is found,the JavaScript begins parsing and splitting the URI into various arrays. This parsing and splitting is done in the lines provided below: var str = window.location.href.substr(window.location.href.indexOf(“?”)+1).split(/#/); var ary = str[0].split(/&/); for(var i=0;i<ary.length;i++){ var split = ary[i].split(/=/),
The vulnerable assignment occurs here: value = split[1];
The JavaScript above essentially grabs a querystring value (attacker supplied) and assigns it to the “value” variable. Later,the “value” variable is used in several places,for example: dojo.config.locale = locale = value; document.getElementsByTagName(“html”)[0].dir = value; theme = value;
Considering the assignments listed above,we have a couple different variables that are tainted. I’ve highlighted the tainted variables in red. Tracing the “theme” assignment shown above,we see the tainted value being passed to a document.write statement,resulting in XSS. var themeCss = d.moduleUrl(“dijit.themes”,theme+”/”+theme+”.css”); var themeCssRtl = d.moduleUrl(“dijit.themes”,theme+”/”+theme+”_rtl.css”); document.write(‘<link rel=”stylesheet”type=”text/css”href=”‘+themeCss+’”>’); document.write(‘<link rel=”stylesheet”type=”text/css”href=”‘+themeCssRtl+’”>’);
The patch checked in by the DojoToolkit team sanitizes the “value” JavaScript variable by allowing only word characters (^\w). Developers Solution1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| if(window.location.href.indexOf("?") >-1){ var str = window.location.href.substr(window.location.href.indexOf("?")+1).split(/#/); var ary = str[0].split(/&/); for(var i=0;i<ary.length;i++){ var split = ary[i].split(/=/), key = split[0], -value = split[1]; +value = split[1].replace(/[^\w]/g,"");// replace() to prevent XSS attack switch(key){ case "locale": // locale string | null dojo.config.locale = locale = value; break; case "dir": // rtl | null document.getElementsByTagName("html")[0].dir = value; break; case "theme": // tundra | soria | noir | squid | nihilo | null theme = value; break; case "a11y": if(value){ testMode = "dijit_a11y";} } } }
// always include the default theme files: if(theme || testMode){
if(theme){ var themeCss = d.moduleUrl("dijit.themes",theme+"/"+theme+".css"); var themeCssRtl = d.moduleUrl("dijit.themes",theme+"/"+theme+"_rtl.css"); document.write('<link rel="stylesheet"type="text/css" href="'+themeCss+'">'); document.write('<link rel="stylesheet"type="text/css" href="'+themeCssRtl+'">'); }
if(dojo.config.parseOnLoad){ dojo.config.parseOnLoad = false; dojo.config._deferParsing = true; }
d.addOnLoad(function(){
// set the classes var b = dojo.body(); if(theme){ dojo.removeClass(b,defTheme); if(!d.hasClass(b,theme)){ d.addClass(b,theme);} var n = d.byId("themeStyles"); if(n){ d.destroy(n);} } if(testMode){ d.addClass(b,testMode);} if(dojo.config._deferParsing){ // attempt to elimiate race condition introduced by this // test helper file. 120ms to allow CSS to finish/process? setTimeout(dojo.hitch(d.parser,"parse",b),120); }
}); }
})(); |
I like Nine Inch Nails,and I like hip-hop. -Axl Rose
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| if(window.location.href.indexOf("?") > -1){ var str = window.location.href.substr(window.location.href.indexOf("?")+1).split(/#/); var ary = str[0].split(/&/); for(var i=0; i<ary.length; i++){ var split = ary[i].split(/=/), key = split[0], value = split[1]; switch(key){ case "locale": // locale string | null dojo.config.locale = locale = value; break; case "dir": // rtl | null document.getElementsByTagName("html")[0].dir = value; break; case "theme": // tundra | soria | noir | squid | nihilo | null theme = value; break; case "a11y": if(value){ testMode = "dijit_a11y"; } } } }
// always include the default theme files: if(theme || testMode){
if(theme){ var themeCss = d.moduleUrl("dijit.themes",theme+"/"+theme+".css"); var themeCssRtl = d.moduleUrl("dijit.themes",theme+"/"+theme+"_rtl.css"); document.write('<link rel="stylesheet"type="text/css"href="'+themeCss+'">'); document.write('<link rel="stylesheet"type="text/css"href="'+themeCssRtl+'">'); }
if(dojo.config.parseOnLoad){ dojo.config.parseOnLoad = false; dojo.config._deferParsing = true; }
d.addOnLoad(function(){
// set the classes var b = dojo.body(); if(theme){ dojo.removeClass(b, defTheme); if(!d.hasClass(b, theme)){ d.addClass(b, theme); } var n = d.byId("themeStyles"); if(n){ d.destroy(n); } } if(testMode){ d.addClass(b, testMode); } if(dojo.config._deferParsing){ // attempt to elimiate race condition introduced by this // test helper file. 120ms to allow CSS to finish/process? setTimeout(dojo.hitch(d.parser, "parse", b), 120); }
}); }
})(); |
if(window.location.href.indexOf(“?”) >-1){ var str = window.location.href.substr(window.location.href.indexOf(“?”)+1).split(/#/); var ary = str[0].split(/&/); for(var i=0;i<ary.length;i++){ var split = ary[i].split(/=/), key = split[0], value = split[1]; switch(key){ case “locale”: // locale string | null dojo.config.locale = locale = value; break; case “dir”: // rtl | null document.getElementsByTagName(“html”)[0].dir = value; break; case “theme”: // tundra | soria | noir | squid | nihilo | null theme = value; break; case “a11y”: if(value){testMode = “dijit_a11y”;} } } } // always include the default theme files: if(theme || testMode){ if(theme){ var themeCss = d.moduleUrl(“dijit.themes”,theme+”/”+theme+”.css”); var themeCssRtl = d.moduleUrl(“dijit.themes”,theme+”/”+theme+”_rtl.css”); document.write(‘<link rel=”stylesheet”type=”text/css”href=”‘+themeCss+’”>’); document.write(‘<link rel=”stylesheet”type=”text/css”href=”‘+themeCssRtl+’”>’); } if(dojo.config.parseOnLoad){ dojo.config.parseOnLoad = false; dojo.config._deferParsing = true; } d.addOnLoad(function(){ // set the classes var b = dojo.body(); if(theme){ dojo.removeClass(b,defTheme); if(!d.hasClass(b,theme)){d.addClass(b,theme);} var n = d.byId(“themeStyles”); if(n){d.destroy(n);} } if(testMode){d.addClass(b,testMode);} if(dojo.config._deferParsing){ // attempt to elimiate race condition introduced by this // test helper file. 120ms to allow CSS to finish/process? setTimeout(dojo.hitch(d.parser,“parse”,b),120); } }); } })(); DetailsAffected Software:Dojo Toolkit SDK Fixed in Version: 1.4.2 Issue Type:Cross Site Scripting (XSS) Original Code: Found Here DescriptionThis was a bug reported by the Gotham Digital Science against the Dojo toolkit SDK. The Dojo toolkit is a popular toolkit used by numerous websites… so in essence this bug provided attackers an opportunity to XSS a large number of websites across the Internet. The bug begins by the capturing of untrusted parameter values from the querystring. This is done by the following JavaScript: 1
| var qstr = window.location.search.substr(1); |
qstr is then split based on the “&” character,proving values for various JavaScript variables including DoJoURL and TestURL. The attacker is free to provide arbitrary values for DoJoURL and TestURL by simply providing the proper querystring values. For example: runner.html?dojoUrl=attacker-controlled&testUrl=attackercontrolled
the attacker supplied values are then used in a document.write() statement,giving the attacker the opprotuntiy to inject arbitrary client side script into any website that happens to include the Dojo library. The vulnerable document.write() statements are provided below: document.write(“<scr”+”ipt type=’text/javascript’djConfig=’isDebug:true’src=’”+dojoUrl+”‘></scr”+”ipt>”); document.write(“<scr”+”ipt type=’text/javascript’src=’”+testUrl+”.js’></scr”+”ipt>”);
The Dojo developers addressed this vulnerability by replacing characters from the attacker controlled input. The specific regular expression used is provided below: value=tp[1].replace(/[<>"']/g,“”);
I see a major issue with this code fix… can you spot it as well? Developers Solution1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| <script type="text/javascript"> // workaround for bug in Safari 3. See #7189 if (/3[\.0-9]+ Safari/.test(navigator.appVersion)) { window.console = { origConsole:window.console, log:function(s){ this.origConsole.log(s); }, info:function(s){ this.origConsole.info(s); }, error:function(s){ this.origConsole.error(s); }, warn:function(s){ this.origConsole.warn(s); } }; } </script> <script type="text/javascript"> window.dojoUrl = "../../dojo/dojo.js"; window.testUrl = ""; window.testModule = ""; // parse out our test URL and our Dojo URL from the query string var qstr = window.location.search.substr(1); if(qstr.length){ var qparts = qstr.split("&"); for(var x=0;x<qparts.length;x++){ - var tp = qparts[x].split("="); - if(tp[0] == "dojoUrl"){ - window.dojoUrl = tp[1]; - } - if(tp[0] == "testUrl"){ - window.testUrl = tp[1]; - } - if(tp[0] == "testModule"){ - window.testModule = tp[1]; - } - if(tp[0] == "registerModulePath"){ - var modules = tp[1].split(";"); - window.registerModulePath=[]; - for (var i=0;i<modules.length;i++){ - window.registerModulePath.push(modules[i].split(",")); - } - } + var tp = qparts[x].split("="),name=tp[0],value=tp[1].replace(/[<>"']/g,""); // replace() to avoid XSS attack + switch(name){ + case "dojoUrl": + case "testUrl": + case "testModule": + window[name] = value; + break; + case "registerModulePath": + var modules = value.split(";"); + window.registerModulePath=[]; + for (var i=0;i<modules.length;i++){ + window.registerModulePath.push(modules[i].split(",")); + } + break; } } document.write("<scr"+"ipt type='text/javascript' djConfig='isDebug:true' src='"+dojoUrl+"'></scr"+"ipt>"); </script> <script type="text/javascript"> try{ dojo.require("doh.runner"); }catch(e){ document.write("<scr"+"ipt type='text/javascript' src='runner.js'></scr"+"ipt>"); } if(testUrl.length){ document.write("<scr"+"ipt type='text/javascript' src='"+testUrl+".js'></scr"+"ipt>"); } </script> <style type="text/css"> @import "../../dojo/resources/dojo.css"; var SHRSB_Globals ={"src":"http:\/\/spotthevuln.com\/wordpress\/wp-content\/plugins\/sexybookmarks\/spritegen_default","perfoption":null}; |
|