Summary

Nathan Partlan and I discovered and reported vulnerabilities in two common Flash applets, SWFUpload and Plupload. SWFUpload’s developers have not released a fix for the XSS issue identified. Plupload’s developers have released v1.5.4 to address the identified CSRF issue.

Both of these applets are present in Wordpress installations. These vulnerabilities were addressed as part of Wordpress 3.3.2.

Vulnerability #1: XSS in SWFUpload ( CVE -2012-3414)

The latest version of SWFUpload (ActionScript code available here) contains the following code:

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 // Get the movie name this . movieName = root . loaderInfo . parameters . movieName ; // **Configure the callbacks** // The JavaScript tracks all the instances of SWFUpload on a page. We can access the instance // associated with this SWF file using the movieName. Each callback is accessible by making // a call directly to it on our instance. There is no error handling for undefined callback functions. // A developer would have to deliberately remove the default functions,set the variable to null, or remove // it from the init function. this . flashReady_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].flashReady" ; this . fileDialogStart_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].fileDialogStart" ; this . fileQueued_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].fileQueued" ; this . fileQueueError_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].fileQueueError" ; this . fileDialogComplete_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].fileDialogComplete" ; this . uploadStart_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].uploadStart" ; this . uploadProgress_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].uploadProgress" ; this . uploadError_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].uploadError" ; this . uploadSuccess_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].uploadSuccess" ; this . uploadComplete_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].uploadComplete" ; this . debug_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].debug" ; this . testExternalInterface_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].testExternalInterface" ; this . cleanUp_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].cleanUp" ; this . buttonAction_Callback = "SWFUpload.instances[\"" + this . movieName + "\"].buttonAction" ;

Each of those callbacks is used as the first parameter to ExternalInterface.call, which executes JavaScript in the context of the current page. Since movieName is derived from user input (a Flash parameter) and a Flash applet can be loaded directly (with parameters in the URL), the Flash applet allows for reflected cross-site scripting. For sites where the applet is hosted on the same domain as the main website, this is a serious security concern.

At this point, I’m not aware of a patched version of the applet source (let me know in the comments if there is one!). My suggestion would be to filter the movieName parameter so that only alpha-numeric characters are allowed.

Proof of Concept: http://demo.swfupload.org/v220/swfupload/swfupload.swf?movieName=%22%5d%29;}catch%28e%29{}if%28!self.a%29self.a=!alert%281%29;//

Vulnerability #2: CSRF in Plupload ( CVE -2012-3415)

The Plupload applet called Security.allowDomain('*') to allow the applet to be used from any domain (so it could be served from S3, for instance). That meant people could interact with the Plupload applet from any other site on the Internet by embedding it on a page and using JavaScript. But due to the way the same-origin policy works in Flash, the applet could still make requests back to the domain on which it was hosted. In addition, people can specify the full URL for an upload request via JavaScript and the result of that request (ie: the HTML of the resulting page) is passed back via JavaScript to the embedding page.

So, if an attacker could convince a target to interact with the applet (by selecting a single file to be uploaded), the attacker could make a request to the domain that the applet was hosted on and read back the full response. That could disclose CSRF tokens or other sensitive information. This issue was especially important for Wordpress installations, where Plupload applets are hosted inside of the wp-includes directory by default.

The issue was resolved by removing the call to Security.allowDomain('*') by default.

Conclusion

Third-party Flash applets are vulnerable to many of the same sorts of attacks as other parts of web applications. However, they are often included in sites without a proper understanding of the security risks.

Update (08/01/2012): I’ve updated the post to include the CVE identifiers assigned to these vulnerabilities.