您的位置:首页 > 编程语言 > ASP

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

2008-02-28 00:36 531 查看
【原文地址】
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劫持攻击。下面是它如何缓和这些攻击的一些细节:

[b]ASP.NET AJAX Web方法在默认情形下是禁止HTTP
GET请求的
[/b]

通过浏览器中的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。

[b]ASP.NET AJAX Content-Type 头信息的验证[/b]

我们有一个由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方法)。

[b]结语[/b]

在默认情形下,在使用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

标签: ASP.NET, .NET, Atlas, Security

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息