There is a built-in validation layer of protection that
ASP.NET enforces for both GET and POST based ASP.NET AJAX web methods, which is
that regardless of the HTTP verb being used, ASP.NET always requires that
the HTTP Content-Type header is set to the value application/json. It this
content type header is not sent, ASP.NET AJAX will reject the request on the
server.
Using the stock quote method shown earlier, an HTTP trace of
an ASP.NET AJAX GET invocation must look like the following:
Listing 3
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
Note that even though the above is a GET request, the
client-side ASP.NET AJAX JSON stack still inserts a Content-Type HTTP header
that tells the server to consider this an AJAX web service request. The
server-side web services stack for ASP.NET AJAX 1.0 always checks for this
specific content type, and if it is not found it will reject the request.
If a malicious developer attempted a cross site request
forgery attack using HTTP GETs against this web service, they might include a
script tag in their page like the following:
Listing 4
<script type="text/javascript" src="http://contoso.com/StockService/Stock.asmx/GetQuotes?symbol=msft" />
However, browsers will not set the Content-Type to
application/json when parsing a <script src=""> element
and making the request. As a result when ASP.NET receives a request made
from a <script /> include, it will not recognize it as a request to an
ASP.NET AJAX web service, and it will result in an error from ASP.NET stating
that it does not recognize the requested URL. This will prevent JSON
Hijacking attempts (even if you have the GET verb enabled for a web method).