allow cross-domain requests to ASP.NET ScriptService - asp.net

I've got a ASP.NET Webservice up and running using the [ScriptService] Attribute. From what I've read from this article:
http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx
ASP.NET by defaults does not allow JSONP requests (injected into the DOM via to deny cross-domain-requests. Its does so by taking 2 measures:
1) only accept POST requests (script injection via always does GET)
2) deny connections sending a HTTP header Content-type other than "Content-type: application/json" (which browsers will not send).
I am familiar with the cross-domain issues and I know what JSONP is and I fully understand, why ASP.NET is by default restricted in that way.
But now, I have my webservice which is a public one, and should be open to everybody. So I explicitly need to enable cross-domain requests via Javascript to my Webservice, so that external websites can retrieve data via my webservice from jquery and alike.
I've already covered step (1) to allow requests via GET by modifiying the ScriptMethod Attribute this way: [ScriptMethod(UseHttpGet=true)]. I've checked with jQuery, GET requests now work (on same-domain). But how to get to fix point (2)?
I know about the Allow-Origin-* headers some browsers support, but afaik its not standard yet, and I don't want to force my users / customers to modify their HTTP headers for using my webservice.
To sum it up: I need the good practice to enable Cross-domain requests for ScriptingService for public Webservices via JSON. I mean there MUST be a way to have a Webservice public, that is what most webservices are about?

Using legacy ASMX services for something like this seems like a lost cause. Try WCF which due to its extensible nature could very easily be JSONP enabled. So if you are asking for best practices, WCF is the technology that you should be building web services on the .NET platform.
Or if you really can't afford migrating to .NET 3.5 at the moment you could also write a custom http handler (.ashx) to do the job.

The jQuery ajax() function does have a 'crossDomain' property.
Pasted from jQuery.ajax()
crossDomain(added 1.5)
Default: false for same-domain requests, true for cross-domain requests
If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain

Related

How does CORS (Access-Control-Allow-Origin header) increase security?

I'm doing some work with this right now and I have to say, it makes no sense at all to me! Basically, I have some CDN server which provides css, images ect for a site. For whatever reason, in order for my browser to stop blocking those resources with a CORS error, I had to have that server (the CDN) add the Access-Control-Allow-Origin header. But as far as I can tell that does absolutely nothing to increase security. Shouldn't the page I request which references those cross-domain resources be telling the browser it's safe to get stuff from the other domain? If that were a malicious domain wouldn't it just have the Access-Control-Allow-Origin set to * so that sites load their malicious responses (you don't have to answer that because obviously they would)?
So can someone explain how this mechanism/feature provides security? As far as I can tell the implementors fucked up and it actually does nothing. The header should be required from the page which references/requests cross-domain resources rather than from that domain being requested.
To be clear; if I request a page at domain A it would make sense for the response to include the Access-Control-Allow-Origin header white listing resources from domain B (Access-Control-Allow-Origin:.B.com), however it makes no sense at all for domain B to effectively white list itself by providing the header; Access-Control-Allow-Origin: which is how this is currently implemented. Can anyone clarify what the benefit of this feature is?
If I have a protected resource hosted on site A, but also control sites B, C, and D, I may want to use that resource on all of my sites but still prevent anyone else from using that resource on theirs. So I instruct my site A to send Access-Control-Allow-Origin: B, C, D along with all of its responses. It's up to the web browser itself to honor this and not serve the response to the underlying Javascript or whatever initiated the request if it didn't come from an allowed origin. Error handlers will be invoked instead. So it's really not for your security as much as it's an honor-system (all major browsers do this) access control method for servers.
Primarily Access-Control-Allow-Origin is about protecting data from leaking from one server (lets call it privateHomeServer.com) to another server (lets call it evil.com) via an unsuspecting user's web browser.
Consider this scenario:
You are on your home network browsing the web when you accidentally stumble onto evil.com. This web page contains malicious javascript that tries to look for web servers on your local home network and then sends their content back to evil.com. It does this by trying to open XMLHttpRequests on all local IP addresses (eg. 192.168.1.1, 192.168.1.2, .. 192.168.1.255) until it finds a web server.
If you are using an old web browser that isn't Access-Control-Allow-Origin aware or you have set Access-Control-Allow-Origin * on your privateHomeServer then your browser would happily retrieve the data from your privateHomeServer (which presumably you didn't bother passwording as it was safely behind your home firewall) and then handing that data to the malicious javascript which can then send the information on to the evil.com server.
On the other hand using an Access-Control-Allow-Origin aware browser and default web configuration on privateHomeServer (ie. not sending Access-Control-Allow-Origin *) your web browser would block the malicious javascript from seeing any data retrieved from privateHomeServer. So this way you are protected from such attacks unless you go out of your way to change the default configuration on your server.
Regarding the question:
Shouldn't the page I request which references those cross-domain
resources be telling the browser it's safe to get stuff from the other
domain?
The fact that your page contains code that is attempting to get resources from a particular server is implicitly telling the web browser that you believe the resources are safe to fetch. It wouldn't make sense to need to repeat this again elsewhere.
CORS makes only sense for Mashup content provider and nothing more.
Example: You are a provider of a embedded maps mashup service which requires a registration. Now you want to make sure that your ajax mashup map will only work for your registered users on their domains. Other domains should be excluded. Only for this reason CORS makes sense.
Another example: Someone misuse CORS for a REST-Service. The clever developer set up a ajax proxy and et voilĂ  you can access from every domain on that service.
Such a ajax proxy would make no sense for a mashup, on the other way the CORS makes no sense for REST-Services, because you could bypass the restriction with a simple http-client.

How do I tell my service (all calls REST/JSON) to handle OPTIONS requests?

I have written a WCF service to return JSON on REST requests. Works great with a browser hitting it. But when my JavaScript hits it, the first request is an OPTIONS request for the url with "Access-Control-Request-Method: GET".
I think I need to handle CORS as documented here. However the suggested code won't compile and the suggested web.config is illegal in places.
What do I need to do so the service will respond appropriately when asked if a GET can be requested on a url?
You may have to enable it in IIS as well: http://encosia.com/using-cors-to-access-asp-net-services-across-domains/

How to show soap request xml for a web service call?

I am using a web method of a company's web service.
This web method requires one parameter when calling it:
CompanyOpereations srv = new CompanyOperations();
srv.getCustomerInfo(input);
How can I see my soap request xml when calling this method?
How do you want to see it? If it's inside the code; I don't know. (Un)Fortunately .NET does a pretty good job of hiding it for the developer.
However, if you just want to debug the calls and nothing else: try Fiddler. It will show you the Request/Response (including headers and everything else) for the webservice calls. This is what we use for debugging webservices. But you can use it for everything that uses the HTTP protocol for communication.

WebTestPlugin and Http Request parameters (Visual Studio Test)

I am using Visual Studio 2010 Ultimate to perform web and load tests. I have a set of web tests that call REST web services that require OAuth credentials and I'm looking for information on how I can access the associated Http Headers and Post body the request. I've created a web test plugin that acts as an Authorization Manager and have overriden the PreWebTest method. When I look at the PreWebTestEventArgs argument, I see the WebTest and its WebTestContext but I don't see any obvious way to access the actual Http Headers or the Post Body where I might be able to insert the OAuth components. Has anyone been able to affect the Http Request with the associated web test? Any insight will be much appreciated. Thanks.
I think you'll need to override PreRequest instead of PreWebTest.
PreRequestEventArgs has the Request property which is the WebTestRequest object that has access to the headers and post body.

Accessing IIS's request handling pipeline to inject a request and get the html response

Is it at all possible to inject a request into IIS for a page, have IIS and ASP.Net handle it as normal, but get the response as html handed back to me programmatically?
Yes, I know that I could connect to port 80 using WebRequest and WebResponse, but that becomes difficult if you are accessing the IIS server from the same physical machine (loopback security controls et al).
Basically, I want to inject the request (eg for http://example.org/MyPage.aspx) between the points at which IIS would normally talk to the browser, and the point at which it would route it to the correct ASP.Net application, and get a response back from IIS between the points at which ASP.Net/IIS applies the httpfilters and hands the html back to the browser.
I'm predominantly working with IIS7 so if there is a solution that works just for IIS7 then thats not an issue.
You could implement a custom HttpModule, which would give you access to the IIS pipeline, including the final response. However, you would still need to initiate a request to IIS to actually kick off processing. Not sure if this would work for you.
From the MSDN documentation:
An HTTP module is an assembly that is
called on every request that is made
to your application. HTTP modules are
called as part of the request pipeline
and have access to life-cycle events
throughout the request. HTTP modules
therefore let you examine incoming
requests and take action based on the
request. They also let you examine the
outgoing response and modify it.
Gave you looked into the WebCkiebt class? You can make the request and get the response HTML.
http://msdn.microsoft.com/en-us/library/system.net.webclient.downloadstring(v=VS.100).aspx

Resources