JSON劫持以及ASP.NET AJAX 1.0是如何避免這些攻擊的

  • 23123
  • 0
  • 2011-07-10

摘要:JSON劫持以及ASP.NET AJAX 1.0是如何避免這些攻擊的

【原文位址】JSON Hijacking and How ASP.NET AJAX 1.0 Avoids these Attacks
【原文發表日期】 Wednesday, April 04, 2007 11:39 AM

最近,由安全研究人員發表的一些報告描述了一些方法,可以被駭客透過利用為絕大多數流行的AJAX框架所用的JSON線上格式來試著利用(exploit)瀏覽器中的跨域腳本。具體來說,這些攻擊使用透過 HTML <script src=""> 包含(include)元素來叫用的HTTP GET請求來繞過由瀏覽器強制執行的「相同來源策略(same origin policy)」(相同來源策略限制了像XmlHttpRequest這樣的JavaScript物件只能叫用當前頁面來自的同一域上的URL),然後尋找利用(exploit)JSON負載內容的方法。

ASP.NET AJAX 1.0 包括了許多預設設置和內建特性,可以防範它免受這些型別的JSON劫持攻擊。下面是它如何緩和這些攻擊的一些細節:

ASP.NET AJAX Web方法在預設情形下是禁止HTTP GET請求的

透過瀏覽器中的HTML <script src=""> 元素來載入的腳本文件只能透過HTTP GET動詞請求來獲取。

在預設情形下, ASP.NET AJAX的web服務層不允許web方法透過HTTP GET 動詞來叫用。譬如,假如一個開發人員編寫了像下面這樣的web服務方法:

[WebMethod]
public StockQuote[] GetQuotes(string symbol) {

 

}

ASP.NET只允許上面的GetQuotes方法透過HTTP POST動詞來叫用,會拒絕透過HTTP GET動詞叫用該方法的任何嘗試。

要使一個ASP.NET AJAX web方法可以透過HTTP GET來訪問,開發人員必須明確地使用ASP.NET的ScriptMethod 特性來標記每個web方法(同時設置UseHttpGet屬性為true):

[WebMethod] 
[ScriptMethod(UseHttpGet
=true)] 

 

public StockQuote[] GetQuotes(string symbol) { 

雖然這類改動很容易做,但它要求一個開發人員有意識地啟用web服務的GET叫用。ASP.NET AJAX web服務絕不會故意地啟用GET,ASP.NET AJAX檔案明確地指出了許多理由(URL篡改的危險是其中一個理由),不贊成啟用GET來叫用web服務端點

註: ASP.NET AJAX UpdatePanel 控制項,以及隨ASP.NET AJAX 1.0一起發佈的其他伺服器控制項,在做異步postback時,並不使用HTTP GET,而是使用HTTP POST。

ASP.NET AJAX Content-Type 標頭資訊的驗證

我們有一個由ASP.NET強制執行的針對基於GET和POST的ASP.NET AJAX web方法的內建的驗證保護層,不管用了哪個HTTP動詞,ASP.NET總是要求HTTP Content-Type標頭資訊是被設置為 application/json 這個值的。假如這個content type標頭資訊並沒有被發送過來,那麼ASP.NET AJAX就會在伺服端拒絕這個請求。

用前面的股票報價方法的例子,一個ASP.NET AJAX GET叫用的跟蹤輸出必須看上去像下面這樣:

 

GET /StockService/Stock.asmx/GetQuotes?symbol=%22msft%22 HTTP/1.1 
Accept: */* 
Accept-Language: en-us,fr;q=0.5 
Referer: http://xxxxxx/StockService/test.aspx 
Content-Type: application/json; charset=utf-8 
UA-CPU: x86 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2) 
Host: xxxxxx 
Proxy-Connection: Keep-Alive 

注意,即使上面只是個GET請求,客戶端ASP.NET AJAX JSON層還是會插入一個Content-Type HTTP標頭的,告訴伺服器把這個請求當作是個AJAX web服務請求。ASP.NET AJAX 1.0的伺服端web服務層總是檢查這個特定的content type,如果沒找到的話,它就會拒絕這個請求。

假如一個惡意的開發人員對這個web服務使用HTTP GET來嘗試跨站請求偽造攻擊時,他們也許會在他們的網頁裡包括一個像下面這樣的腳本標識:

<script type=」text/javascript」 src=」http://contoso.com/StockService/Stock.asmx/GetQuotes?symbol=msft」 /> 

但是,瀏覽器在分析<script src="">元素,發送請求時,是不會Content-Type 設置成application/json的。結果是,ASP.NET 將接收到一個來自 <script />包含的請求,但它不會將其認為是對ASP.NET AJAX web服務的一個請求,這會造成一個ASP.NET錯誤,宣告它不認識被請求的URL。這就會避免JSON劫持嘗試(即使你有一個允許GET動詞叫用的web方法)。

結語

在預設情形下,在使用JSON叫用web方法時,ASP.NET AJAX 1.0只允許使用HTTP POST動詞,這意味著你不會無意中允許瀏覽器透過HTTP GET來叫用方法。

ASP.NET AJAX 1.0 要求在透過GET和POST叫用AJAX web服務時,Content-Type標頭被設置成「application/json」。 不包含這個頭資訊的JSON請求會被ASP.NET伺服器所拒絕。這意味著,你不能透過<script src=""> 包含(include)來叫用ASP.NET AJAX web方法,因為在像這樣請求JavaScript文件時,瀏覽器不允許附加自訂的content-type標頭資訊。

希望本文對你有所幫助,

Scott

標籤: , , ,