前段時間測試人員報了一個flash的xss bug,經分析用了Loader.loadBytes且沒作數據流格式校驗的程序都會中招,自測方法只需一行代碼:html
ExternalInterface.call('alert', ‘msg from flash’);
編譯後把後綴名改成jpg或png等圖片格式,去新浪微博主站選擇第一種圖片上傳方式……xss
雖然用戶通常不會上傳來歷不明的圖片,可是本着好奇心仍是搞了一下怎麼防止。用Flash的FileReference的type判斷文件格式很原始,真的只是從文件的後綴名判斷的,因此改了後綴很明顯會有問題……測試
解決方法只能是讀取數據流裏面真實的格式數據了。用winHex看了一下各類圖片的文件流,文件頭的不定長度(24位至64位二進制數據)的數據是標識文件格式的數據塊。因此用ByteArray讀取這部分數據便可判斷文件格式。因爲須要鑑定的圖片格式是固定的幾種,因此只取前面24位二進制數據便可判斷這幾種格式。spa
代碼:code
var file: FileReference = new FileReference(); var fileFilter:FileFilter = new FileFilter('圖片文件:(*.jpg, *.jpeg, *.gif, *.png, *.bmp)','*.jpg; *.jpeg; *.gif; *.png; *.bmp'); stage.addEventListener(MouseEvent.CLICK, function(evt: MouseEvent) { file.browse([fileFilter]); }); file.addEventListener(Event.SELECT, function(evt: Event) { file.addEventListener(Event.COMPLETE, onLoadCpl); file.load(); }); function onLoadCpl(evt: Event): void { file.removeEventListener(Event.COMPLETE, onLoadCpl); var byteArray:ByteArray = evt.target.data as ByteArray; var fileTypeHex: String = byteArray.readUnsignedByte().toString(16) + byteArray.readUnsignedByte().toString(16) + byteArray.readUnsignedByte().toString(16); trace(fileTypeHex); if(fileTypeHex == ‘ffd8ff’ || fileTypeHex == ‘89504e’ || fileTypeHex == ‘474946’ || fileTypeHex == ‘424de8’) { //分別是jpg&jpeg、png、gif、bmp的hex
loadByte(byteArray);
} else {
trace(‘文件格式不正確’);
}
}
function loadByte(byteArray: ByteArray): void {
var loader: Loader = new Loader();
//loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e: Event) {});//加載圖片
loader.loadBytes(byteArray);
}
對比一下用winHex讀取的文件數據:htm
jpg&jpeg:blog
png:圖片
gif:rem
bmp:get
徹底一致,大功告成~
==================================================
做者:hotcho
出處:http://www.cnblogs.com/cos2004/p/3198244.html
==================================================