Spinning –Defense in Depth

Details

Affected Software:Dojo Toolkit

Fixed in Version:1.4.1

Issue Type:Defense in Depth

Original Code: Found Here

Description

This was a vulnerability affecting the Dojo toolkit.   Apparently,the dojo toolkit shipped with a SWF file that had a few vulnerabilities.  This particular vulnerability affected one of those SWF files.  First,SWF files are compiled files,however they can be decompiled.  Unlike traditional server side web application languages (PHP,ASP,JSP…etc),SWF files are downloaded and rendered on the clientside.  Decompiling the SWF file gives the attacker full access to the ActionScript source code for the SWF application.

In this particular SWF file,we see that the developers explicitly set the Security.allowDomain to “*”.  This makes it so SWF flies from other,external domains can include the Dojo toolkit SWF file and script/access its internal functionality.

The Dojo toolkit devs fixed this particular issue by removing the allowDomain call and adding an Externalinterface call checking to see if a particular wrapper was available in HTML.  If you’re interested in Flash security,an excellent presentation on Flash security given by Stefano Di Paola can be found here:

http://www.slideshare.net/guestb0af15/owasp-wasc-app-sec2007-san-jose-finding-vulnsin-flash-apps

Developers Solution

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
public class FLVideo extends Sprite {
private var videoUrl:String;
private var video:Video;
private var connection:NetConnection;
private var autoPlay:Boolean;
private var videoStream:NetStream;
private var videoWidth:Number;
private var videoHeight:Number;
private var _currentVideo:VideoContainer;
private var preview:VideoContainer;
private var currentVolume:Number = 1;
private var isFullscreen:Boolean = false;
private var playlist:VideoPlaylist;
private var hasPlaylist:Boolean = false;
private var mode:String = "preview";

public function FLVideo() {
-    Security.allowDomain("*");
+    var secure:* = ExternalInterface.call("swfIsInHTML");
+    if(secure !== true){
+        return;
+    }
+    //Security.allowDomain("*");

stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.RESIZE,onStageResize);
stage.addEventListener(FullScreenEvent.FULL_SCREEN ,onFullscreenChange);
stage.addEventListener(MouseEvent.CLICK,onClick);

var obj:Object = LoaderInfo(this.root.loaderInfo).parameters;
trace(obj)

if(!obj.videoUrl){
obj = {
autoPlay:true,
isDebug:true,
videoUrl:"demo_video.flv"
};
}


// ugh - booleans not coming through
if(obj.autoPlay===true || obj.autoPlay=="true"){
autoPlay = true;
}

if(obj.volume) {
currentVolume = obj.volume;
}

if(obj.isDebug===true || obj.isDebug=="true"){
console.isDebug(true);
Tracer.init({both:true})
Tracer.log("FLVideo initialized...")
}

+    Tracer.log("secure?::",secure)
MovieIdentity.identity = obj.id || "default";
this.playlist = new VideoPlaylist(autoPlay,currentVolume);

if(obj.videoUrl) {
videoUrl = obj.videoUrl;
}

preview = new VideoContainer(videoUrl,autoPlay,currentVolume);
addChild(preview);
provideCallbacks();
}


public function get currentVideo():VideoContainer{

if(mode=="playlist"&&hasPlaylist){
return this.playlist.current;
}else{
return preview;
}
}

Everything – Cross Site Scripting

Details

Affected Software:Dojo Toolkit SDK

Fixed in Version: 1.4.2

Issue Type:Cross Site Scripting (XSS)

Original Code: Found Here

Description

This 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 Solution

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
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:""};