Flash應用安全規範
Author: jianxin [80sec]
EMail: jianxin#80sec.com
Site: http://www.80sec.com
Date: 2009-07-25
From: http://www.80sec.com/release/flash-security.txt
[ 目錄 ]
0×00 前言
0×01 安全的服務端flash安全政策
0×02 安全的用戶端flash安全規範
0×03 flash安全的checklist
flash作為一款浏覽器的第三方插件,是對浏覽器功能的延伸,已經是web必不可少的元素。但是這種延伸必然帶來不安全的因素,相比于安全性已經得到磨練的浏覽器來說,flash絕對是用戶端安全的一個軟肋(包括在比較神秘的漏洞挖掘領域,也是這個觀點),同樣flash在頁面展示時所含有的豐富功能,在某些情況下你甚至可以認為它等同于javascript,甚至更為危險。浏覽器所貫徹的域安全政策被flash所打破,用戶端所做的種種過濾也同樣被flash所打破(隻要你還使用flash)。但是flash也已經感覺到了這個問題,并且時時在改進,在設計上也引入了一些比較好的安全機制,恰當的使用這些安全機制可以避免你的應用程式遭到攻擊。80sec将從實際的一些經驗總結出一些供參考的flash使用規範,規範将從服務端應用程式的安全設計和用戶端的flash安全使用兩個角度來說明這個問題。
應用程式安全設計的時候應該秉承最小化原則,在flash的大部分應用中,由于功能需求就經常需要跨域擷取資料。域安全是浏覽器安全的基本政策,flash作為浏覽器的擴充允許跨域擷取資料就從根本上打破了浏覽器的安全性。flash以flash檔案存儲域名作為它的目前域,如果需要擷取其他伺服器上的資料就會發生跨域行為,而且該跨域行為會繼承使用者浏覽器裡的認證資訊,限制不嚴格時将導緻安全漏洞,打破我們的整個用戶端安全模型。flash在跨域時唯一的限制政策就是crossdomain.xml檔案,該檔案限制了flash是否可以跨域擷取資料以及允許從什麼地方跨域擷取資料。通過嚴格控制該政策檔案我們就可以為應用程式安全和功能上尋找到一個平衡點。
典型的crossdomain.xml檔案政策
<code><?xml version="1.0"?> <cross-domain-policy> <allow-access-from domain="*.80sec.com" /> </cross-domain-policy></code>
其中最主要的政策是allow-access-from表示允許來自哪些域的跨域請求,早期的flash允許從其他位置載入自定義的政策檔案,目前最新版的flash在接受自定義的政策檔案之前會去檢查主目錄的crossdomain.xml來判斷是否接受自定義政策檔案。該選項由
<code><site-control permitted-cross-domain-policies="by-content-type"/></code>
節點控制,不加該選項時,預設情況下flash不加載除主政策檔案之外的其他政策檔案,即隻接受根目錄裡的/crossdomain.xml。這對于防止利用上傳檔案來定義自己政策檔案的攻擊非常有效。為了在某些條件下需要啟用其他政策檔案,我們需要設定permitted-cross-domain-policies,設定為by-content-type時将會隻允許http頭為text/x-cross-domain-policy的政策檔案,當為all時則允許所有的text/xml等格式的政策檔案。
應用程式在設計的時候按照最小化原則
1 将檔案上傳和應用的域名分開,防止通過上傳flash檔案直接獲得域操作的權限。
2 對于不需要使用flash的應用嚴禁在域名目錄下部署flash政策檔案。
3 對于有功能需求的應用遵循最小化原則将域名限制到最小的範圍,有安全需求的應用應該明确允許跨域請求的域,禁止直接使用*通配符,這将導緻跨域通路權限的擴散。
譬如http://sns.80sec.com/crossdomain.xml
就對權限設定過泛,可能導緻其他安全政策的繞過(如繞過csrf等等)
4 對于有高安全需求的應用,在限制域名的前提下,将需要被flash通路的應用限制到指定目錄,并且在flash内指定政策檔案到該目錄以将所有通路權限限制到單一目錄。
如果login.80sec.com中的某個功能如login需要對所有域名開放,如果配置根目錄crossdomain.xml
<code><?xml version="1.0"?> <cross-domain-policy> <allow-access-from domain="*" /> </cross-domain-policy></code>
不是一個好的政策因為他不隻會開放login同時會開放如chgpassword等其他的服務給使用者,我們需要配置主政策檔案
<code><?xml version="1.0"?> <cross-domain-policy> <site-control permitted-cross-domain-policies="all"/> </cross-domain-policy></code>
然後自定義政策檔案到一個目錄如/flash/crossdomain.xml
并且将login應用部署到/flash/目錄,使用者的通路将被限制到/flash/下面,無法對其他功能進行操作。
控制好flash安全政策并不是安全的全部,這樣隻能保證服務端的安全。由于一些功能上的原因,譬如為了追求良好的使用者體驗,為了讓無聊的使用者可以在頁面共享各種flash,為了把頁面做得華麗麗的,我們往往需要在頁面内容裡嵌入flash,這個時候安全性就會被抛到一邊(我們還是建議如果不需要的話還是少用這種動态的東西)。我們在一個頁面引入一個flash時,一般的做法是下面這種形式:
<code><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" name="Main" width="1000" height="600" align="middle" id="Main"> <embed flashvars="site=&sitename=" src='Loading.swf?user=453156346&key=df57546b-c68c-4fd7-9f9c-2d105905f132&v=10950&rand=633927610302991250' width="1000" height="600" align="middle" quality="high" name="Main" allowscriptaccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object></code>
由于flash的強大,并且在頁面元素裡基本等同于script這種危險的标簽,對于這點,flash已經有所考慮,在引入flash的時候flash提供了控制屬性,其中與安全最為關鍵的是AllowScriptAccess屬性和allowNetworking屬性。其中AllowScriptAccess控制flash與html頁面的通訊,可選的值有:
<code>always //對與html的通訊也就是執行javascript不做任何限制 sameDomain //隻允許來自于本域的flash與html通訊,這是預設值 never //絕對禁止flash與頁面的通訊</code>
預設情況下的選項是sameDomain,這個時候某些場景下看起來也是足夠安全了,但是我們還是能看到經常有程式允許将這個選項設定為always,而即使是sameDomain也不是在所有場景下都安全的,考慮如論壇這樣的程式,上傳和展現都是在同一個域的情況下,就不存在任何安全性可言了,我們強烈建議該選項為never,如果你選擇sameDomain或者always我也希望你清楚自己在做什麼。
allowNetworking控制flash與外部的網絡通訊,可選的值包括:
<code>all //允許使用所有的網絡通訊,也是預設值 internal //flash不能與浏覽器通訊如navigateToURL,但是可以調用其他的API none //禁止任何的網絡通訊</code>
但是最近更新的flash用戶端貌似是隻要AllowScriptAccess被設定那麼包括navigateToURL都不能使用,在官方文檔上也隻看到簡簡單單的一句道歉,但是這樣的确從某些程度上提高了嵌入flash的安全性。但是即使不跳轉,我們還是能做很多事情,當我們将flash直接嵌入到頁面又沒有設定allowNetworking時,我們就可以做csrf之類猥瑣的事情,更要命的是這種形式的csrf支援POST請求,referer來源為swf檔案所在位址或者為空,同時發送所有cookie而不像圖檔那些隻能發送session
cookie,而且基本沒有任何的痕迹,基本秒殺那些沒有做token保護的csrf防範了,之前的開心網犯的就是這個錯誤,我們強烈建議該選項為none,如果你不選擇這個建議你也要清楚自己在做什麼。
1 檢查自己的網站的根目錄的crossdomain.xml
好孩子:
<code></code>
http://mail.google.com/crossdomain.xml
http://youa.baidu.com/crossdomain.xml
http://www.adobe.com/crossdomain.xml
壞孩子:
http://www.youku.com/crossdomain.xml
http://www.renren.com/crossdomain.xml
http://www.taobao.com/crossdomain.xml
我承認所有的利用都離不開場景,有的時候如果實在沒有辦法修改這個crossdomain.xml(這個情況的确存在,譬如某些變态功能的需要),那麼就可以考慮在應用程式擷取資料時對送出的資料做校驗,譬如當請求的頭裡包括x-flash-version時,就可以判定來源是flash而不予響應,但這的确不是一種優美的解決辦法。
2 檢查自己網站引入flash的代碼
有AllowScriptAccess和allowNetworking麼?如果沒有,那是不是我這個應用設計已經很安全足夠抵禦各種攻擊了?
如果想針對安全問題做測試,fly_flash是友善的攻擊用戶端的好夥伴(參見開心網蠕蟲),如果想針對第一種錯誤的政策檔案突破csrf等做測試就還得自己寫源碼了。另外,良好的設計的最大敵人就是壞的實作,原因也是各個程式之間天然的心之壁壘,猜猜
<code><embed allowscriptaccess="always" allowscriptaccess="never" height=384 width=454 src=http://www.80sec.com/fly_flash.swf?sec80=http://www.80sec.com/fly_flash.txt&x.swf wmode="transparent" loop="false" autostart="false"></code>
這段代碼的結果是什麼?