發表時間:2007-4-29 13:58:00
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="http://www.blog.com.cn/"> 包含(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://www.blog.com.cn/"> 元素來裝載的指令檔只能通過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="http://www.blog.com.cn/">元素,發送請求時,是不會把 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="http://www.blog.com.cn/"> 包含(include)來調用ASP.NET AJAX web方法,因為在象這樣請求JavaScript檔案時,瀏覽器不允許附加自訂的content-type頭資訊。
希望本文對你有所協助,
Scott