Re: CSRF vulnerability in Tyler's GuestXHR protocol?

Hi Adam,

Responses inline below...

On Thu, Nov 5, 2009 at 8:56 AM, Adam Barth <w3c@adambarth.com> wrote:
> Hi Tyler,
>
> I've been trying to understand the GuestXHR protocol you propose for
> replacing CORS:
>
> http://sites.google.com/site/guestxhr/maciej-challenge
>
> I don't understand the message in step 5.  It seems like it might have
> a CSRF vulnerability.  More specifically, what does the server do when
> it receives a GET request for https://B/got?A=secret123?

Think of the resource at /got as like an Inbox for accepting an "add
event" permission from anyone. The meta-variable "A" in the query
string, along with the secret, is the URL to send events to. So a
concrete request might look like:

GET /got?site=https%3%2F%2Fcalendar.example.com&s=secret123
Host: upcoming.example.net

When upcoming.example.net receives this request, it might:

1) If no association for the site exists, add it
2) If an existing association for the site exists respond with a page
notifying the user of the collision and asking if it should overwrite
or ignore.

Notice that step 6 is a response from Site B back to the user's browser.

Alternatively, the response in step 6 could always be a confirmation
page asking the user to confirm any state change that is about to be
made. So, the page from the upcoming event site might say:

"I just received a request to add a calendar to your profile. Did you
initiate this request? <yes> <no>"

Note that such a page would also be a good place to ask the user for a
petname for the new capability, if you're into such things, but I
digress...

> The slides say "Associate user,A with secret123."  That sounds like
> server B changes state to associate secret123 with the the pair (user,
> A).  What stops an attacker from forging a cross-site request of the
> form https://B/got?A=evil123?

In the design as presented, nothing prevents this. I considered the
mitigation presented above sufficient for Maciej's challenge. If
desired, we could tighten things up, without resorting to an Origin
header, but I'd have to add some more stuff to the explanation.

>  Won't that overwrite the association?

That seems like a bad idea.

> There doesn't seem to be anything in the protocol that binds the "A"
> in that message to server A.

The "A" is just the URL for server A.

> More generally, how does B know the message https://B/got?A=secret123
> has anything to do with "user"?  There doesn't seem to be anything in
> the message identifying the user.  (Of course, we could use cookies to
> do that, but we're assuming the cookie header isn't present.)

This request is just a normal page navigation, so cookies and such
ride along with the request. In the diagrams, all requests are normal
navigation requests unless prefixed with "GXHR:".

We used these normal navigation requests in order to keep the user
interface and network communication diagram as similar to Maciej's
solution as possible. If I were approaching this problem without that
constraint, I might do things differently, but that wasn't the goal of
this exercise.

> Can you help me understand how the protocol works?

My pleasure. Please send along any follow up questions.

(I would have chosen a different Subject field for these questions though)

> P.S., It also seems that the protocol does not comply with the HTTP
> specification because the server changes state in response to a GET
> request.  Presumably, you mean to use a 307 redirect and a POST
> request.  Unfortunately, that means the protocol will generate a
> warning dialog in Firefox and will fail completely in Safari 4.

I just said 303 because it was the most succinct way of expressing the
relevant part of the communication. In deployment, a better solution
would be to send back a normal 200 response with JavaScript code that
does an automated form POST of the same data to Server B.

--Tyler

-- 
"Waterken News: Capability security on the Web"
http://waterken.sourceforge.net/recent.html

Received on Thursday, 5 November 2009 20:06:29 UTC