6

I've built an application that uses jQuery and JSON to consume an ASP.NET .asmx web service to perform crud operations. The application and .asmx are on the same domain. I dont mind people consuming the read operations of the .asmx remotely but dont want people randomly deleting stuff!!!

I can split the methods i'd like to be publicly accessible and the 'hidden' ones into 2 web services. How can I lock calls to the 'hidden'.asmx web service to the same domain that its hosted in?

Thanks in advance.

Edit: Can someone comment on this, seems plausible ( source: http://www.slideshare.net/simon/web-security-horror-stories-presentation ): Ajax can set Http headers, normal forms cant. Ajax requests must be from the same domain.

So "x-requested-with" "XMLHttpRequest" requests must be from the same domain.

jdee
  • 11,612
  • 10
  • 38
  • 36
  • Do you have a specific question about that presentation? Everything is definitely used to compromise sites, but with basic protections you are safe. – Peter J Mar 08 '09 at 19:26
  • yes its the part where it says you can rely on x-requested-with to tell you its from the same domain and therefore safe. ive asked the same question elsewhere today and every is convinced that any http header can be spoofed. im not so sure. anyway, ive solved this in another manner ( major refactor) – jdee Mar 08 '09 at 19:57
  • but thanks very much for your help. it definately put me on the right track to solve my real world problem. – jdee Mar 08 '09 at 19:57

3 Answers3

8

There are two scenarios you need to secure with web services:

  1. Is the user authenticated?
  2. Is the action coming from my page?

The authentication piece is already taken care of if you're using Forms Authentication. If your web service sits in a Forms Authentication-protected area of the site, nobody will be able to access your web services unless they're logged in.

The second scenario is a slightly trickier story. The attack is known as CSRF or XSRF (Cross Site Request Forgery). This means that a malicious website performs actions on behalf of your user while they're still logged in to your site. Here's a great writeup on XSRF.

Jeff Atwood sort of sums it all up in the link above, but here is XSRF protection in four steps:

  1. Write a GUID to your user's cookie.
  2. Before your AJAX call, read this value out of the cookie and add it to the web service POST.
  3. On the server side, compare the FORM value with the cookie value.
  4. Because sites cannot read cookies from another domain, you're safe.
Peter J
  • 57,680
  • 8
  • 38
  • 45
-1

In AJAX the browser makes the calls, so even if you were to check that the domain is the same it wouldnt be secure enough because it can easily be faked.

You need to use some sort of authetication/autharization tokens (preferably with a time out) to keep things safe.

Sruly
  • 10,200
  • 6
  • 34
  • 39
  • can you elaborate? how could i the token system you mention? – jdee Mar 07 '09 at 21:02
  • >that should be 'how could i create the token system you mention?' thanks – jdee Mar 07 '09 at 21:02
  • You have to issue a key that the ajax has to send back when the user requests a crud operation. This key should expire after a short period of time, this way only pages that were generated from your server have the key and can perform the operations – Sruly Mar 07 '09 at 21:09
  • There are probably frameworks for this but I dont know of any. – Sruly Mar 07 '09 at 21:09
  • hmm still no clearer. I understand what you are saying but there are so many questions left that I cant close this question out. what issues the key? the web service? how can the webservice be sure the key requester is legit? – jdee Mar 07 '09 at 23:21
  • The web service issues the key. It can be sure the initaial request is legit because it is the regular http request for the page. in the page you can use all the regular auth stuff. Then when you are sure of the legit request you issue a key that gets stored on the client for a limited time span – Sruly Mar 07 '09 at 23:37
  • and the page stores the key in a hidden field and gets posted to the server with each request? whats to stop someone just parsing out the key and fake submitting it? thanks very much for sharing your expertise by the way! – jdee Mar 07 '09 at 23:52
  • I presume the web service has to keep track of the keys it has issued too, and manage the timeouts of those keys? – jdee Mar 07 '09 at 23:56
  • Sruly, a good answer and definitely in the right direction, but I think an expiring key is unnecessary. – Peter J Mar 08 '09 at 07:10
-1

Quick and dirty solution would be to use IP address restrictions to allow only your domain's IP address access via IIS.

Probably better would be using HTTP authentication. There are many ways to do this, I found Authentication in ASP.NET Web Services a helpful overview.

Eddie Groves
  • 33,851
  • 14
  • 47
  • 48