CVE-2014-1869: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Multiple cross-site scripting (XSS) vulnerabilities in ZeroClipboard.swf in ZeroClipboard before 1.3.2, as maintained by Jon Rohan and James M. Greene, allow remote attackers to inject arbitrary web script or HTML via vectors related to certain SWF query parameters (aka loaderInfo.parameters).
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Published: 2014-02-08T00:55Z
Repository: https://github.com/zeroclipboard/zeroclipboard
Language: Other
Files changed: src/flash/ZeroClipboard.as
Commit date: 2014-01-31 12:01:13 -0600
Commit message: Hardening sanitization technique in Flash

Diff: diff --git a/ZeroClipboard.swf b/ZeroClipboard.swf
index 56637ff..6a989e9 100644
Binary files a/ZeroClipboard.swf and b/ZeroClipboard.swf differ
diff --git a/src/flash/ZeroClipboard.as b/src/flash/ZeroClipboard.as
index f2a4d2b..4830d77 100755
--- a/src/flash/ZeroClipboard.as
+++ b/src/flash/ZeroClipboard.as
@@ -47,17 +47,17 @@ package {
       // Get the flashvars
       var flashvars:Object = LoaderInfo( this.root.loaderInfo ).parameters;
 
       // Allow the SWF object to communicate with a page on a different origin than its own (e.g. SWF served from CDN)
       if (flashvars.trustedOrigins && typeof flashvars.trustedOrigins === "string") {
-        var origins:Array = flashvars.trustedOrigins.split("\\").join("\\\\").split(",");
+        var origins:Array = ZeroClipboard.sanitizeString(flashvars.trustedOrigins).split(",");
         flash.system.Security.allowDomain.apply(null, origins);
       }
 
       // Enable complete AMD (e.g. RequireJS) and CommonJS (e.g. Browserify) support
       if (flashvars.jsModuleId && typeof flashvars.jsModuleId === "string") {
-        jsModuleId = flashvars.jsModuleId.split("\\").join("\\\\");
+        jsModuleId = ZeroClipboard.sanitizeString(flashvars.jsModuleId);
       }
 
       // invisible button covers entire stage
       button = new Sprite();
       button.buttonMode = true;
@@ -81,10 +81,20 @@ package {
 
       // signal to the browser that we are ready
       dispatch("load", ZeroClipboard.metaData());
     }
 
+    // sanitizeString
+    //
+    // This private function will accept a string, and return a sanitized string
+    // to avoid XSS vulnerabilities
+    //
+    // returns an XSS safe String
+    private static function sanitizeString(dirty:String): String {
+      return dirty.replace(/\\/g,"\\\\")
+    }
+
     // mouseClick
     //
     // The mouseClick private function handles clearing the clipboard, and
     // setting new clip text. It gets this from the clipText private variable.
     // Once the text has been placed in the clipboard, It then signals to the
@@ -97,11 +107,11 @@ package {
       // Flash 10 API, so we need to use this until we can figure out an alternative
       flash.system.System.setClipboard(clipText);
 
       // signal to the page it is done
       dispatch("complete", ZeroClipboard.metaData(event, {
-        text: clipText.split("\\").join("\\\\")
+        text: ZeroClipboard.sanitizeString(clipText)
       }));
 
       // reset the text
       clipText = "";
     }

Vulnerable code:         var origins:Array = flashvars.trustedOrigins.split("\\").join("\\\\").split(",");
        jsModuleId = flashvars.jsModuleId.split("\\").join("\\\\");
        text: clipText.split("\\").join("\\\\")
Fixed code:         var origins:Array = ZeroClipboard.sanitizeString(flashvars.trustedOrigins).split(",");
        jsModuleId = ZeroClipboard.sanitizeString(flashvars.jsModuleId);
    // sanitizeString
    //
    // This private function will accept a string, and return a sanitized string
    // to avoid XSS vulnerabilities
    //
    // returns an XSS safe String
    private static function sanitizeString(dirty:String): String {
      return dirty.replace(/\\/g,"\\\\")
    }

        text: ZeroClipboard.sanitizeString(clipText)