Subject: Re: [http-auth] CSRF Prevention

From: "Steingruebl, Andy" <[email-masked]>
Date: Tue, 5 Jul 2011 09:41:51 -0600

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf Of Tim

> Failing that, as a final possibility (and the reason I am posting this
> here) is that we could rely on a better HTTP authentication mechanism to
> help us enforce CSRF protections.  Since Referer logic is already baked in to
> browsers, and any HTTP authentication mechanism would also need to be
> baked in to browsers, why not bake something like Referer into the HTTP
> authentication mechansim to help application developers validate the origin
> of requests?  Essentially, make Referer information more reliable and more
> privacy sensitive.
> 
> The most obvious approach would be to require an origin domain parameter
> in the HTTP authentication mechanism, have it signed, and then let
> application developers check that upon receipt.

Several people have in the past proposed an "Origin" header.

Among them Adam Barth, Collin Jackson, and even folks at Mozilla who have a nice write-up here:
https://wiki.mozilla.org/Security/Origin

I haven't seen your "ACTION" verb proposal before, but others here may have pointers to similar previous research.

Other ideas proposed in this space have been cookies that aren't sent cross-domain. So, a website can choose whether certain cookies are sent on cross-site requests.  

- Andy

---

From: Nico Williams <[email-masked]>
Date: Tue, 5 Jul 2011 16:16:54 -0500

I believe authentication is orthogonal to CSRF.

It would be nice to have what you might call stronger type and
semantic safety.  An IMG tag should refer to images, thus a header
that indicates the type of data expected in the response might help.
Moreover, an IMG should never do anything other than a GET (or HEAD --
and any other non-data-modifying verbs), and the GET is expected to
have no side effects (other than updating atime on a filesystem,
perhaps).  The browser knows these details, so it could tell the
server "don't do anything, just give me back an image", and the server
could respond with some error indicating that the browser is likely
being subjected to a CSRF attach.

The proposed Origin header would fall into the category of
improvements that add stronger type and/or semantic safety.

It'd be nice to have response headers by which the server can indicate
that it did perform the requested type/semantic checking.  Also, it'd
be nice to have a way to add "critical" headers -- headers that
servers are supposed to understand else they must reject the request.

Nico
--

---

From: Tim <[email-masked]>
Date: Tue, 5 Jul 2011 15:11:40 -0700

Hi Andy,

Thanks for taking the time to read my monologue.

> https://wiki.mozilla.org/Security/Origin

I have no doubt this has been covered before.  The Origin header seems
pretty straight-forward, though it doesn't attempt to provide privacy
if users don't want to expose what sites they are coming from.  Since
Origin it doesn't include the full URI, it isn't as bad as Referer,
but still, there are many instances where users have interal web
servers pointing out to the Internet and would rather their internal
host names be kept private. 

So one approach to achieve what I'm am proposing is to have the HTTP
authentication mechanism authenticate an Origin header.  Changing
Origin to a salted hash of the Origin might be a nice upgrade.

> I haven't seen your "ACTION" verb proposal before, but others here may have pointers to similar previous research.

Well, I'm only now mentioning it. =)  I've floated the idea to a
couple of security people, but haven't tried to write anything up.

The insecurity of the Internet keeps me so busy that I can't find time
to sharpen the axe and propose formal fixes, let alone see them
through to standardization.

> Other ideas proposed in this space have been cookies that aren't sent cross-domain. So, a website can choose whether certain cookies are sent on cross-site requests.  

Not sure I understand how this would help.

tim

---

From: Tim <[email-masked]>
Date: Tue, 5 Jul 2011 15:25:39 -0700

Hi Nico,

> I believe authentication is orthogonal to CSRF.

I don't agree.  The reason why CSRF works is because we're using
broken, layered authentication systems that assume any request at one
layer (HTTP) is ok to embed in a secure stream at the lower layer
(SSL/TLS).  Essentially, CSRF can be seen as a spoofed request within
the encrypted channel.  Notice how similar it is, in exploitation, to
the TLS renegotiation flaw?  You're just issuing a blind request.

The layer that makes requests needs to be tying the source origin in
with the layer doing authentication.  By doing so, you'd be preventing
problems like what we had with (old) Flash's ability to forge headers
in a cross-origin way.  While I don't think it is reasonable to
support that kind of behavior in client-side technologies, preventing
this will also make the protocols much more resilient in the face of
other attacks.

> being subjected to a CSRF attach.

It would be nice if browser implementors considered these problems
when they added gobs and gobs of features into HTML, JavaScript and
other client-side technologies.  Unfortunately, they didn't, and going
back to fix them doesn't seem tractable to me.  Restricting requests
that come out of IMG tags might be somehow possible, but doing that
for JavaScript form submission is a different beast.

So when it comes to client-side enforcement, this is where a
different, restricted, HTTP method (ACTION/PUT) could come in.  This
would be far easier to implement in browsers since IMG/LINK/other tags
already only do GET, forms can only do GET/POST, and XMLHttpRequest is
already same-origin.

I'm not against client-side enforcement, but I don't think it is
reasonable to try and enforce new restrictions on existing
cross-origin requests.  Trying to prevent things like JSON data theft
might also be difficult if protection is only offered client-side.

Thanks,
tim

---

From: "Steingruebl, Andy" <[email-masked]>
Date: Tue, 5 Jul 2011 16:37:16 -0600

> From: Tim [mailto:[email-masked]]
> 
> > Other ideas proposed in this space have been cookies that aren't sent
> cross-domain. So, a website can choose whether certain cookies are sent on
> cross-site requests.
> 

A site would set its authentication cookies such that the browser will only send them when the referrer is the same site.   As a consequence, CSRF attacks can't happen if the "source page" isn't on the domain of the cookie.  It will prevent cross-domain actions because the browser won't send the necessary authentication data.

In some sense similar to what Microsoft has done with XDR so that one can still build unauthenticated mashups, but the control would be under the domain setting the cookies.

- Andy

---

From: Tim <[email-masked]>
Date: Tue, 5 Jul 2011 15:41:18 -0700

> A site would set its authentication cookies such that the browser will only send them when the referrer is the same site.   As a consequence, CSRF attacks can't happen if the "source page" isn't on…

Ok, that makes more sense.  

Of course, this wouldn't protect sites using HTTP authentication.
Since using cookies for authentication comes with so many other
problems, a mechanism that isn't tied to cookies makes more sense to
me.

tim

---

From: Nico Williams <[email-masked]>
Date: Tue, 5 Jul 2011 17:49:02 -0500

> the TLS renegotiation flaw?  You're just issuing a blind request.

But this is a confused deputy problem.  The problem is not how to
authenticate the deputy, but how to prevent its confusion.

As for TLS renegotiation, there we had two cryptographic channels
where one needed to bind to the other.  But what would we have to bind
here?  Crypto at the HTTP layer to the TLS channel?  Sure, but how
would crypto at the HTTP layer prevent the deputy from getting
confused?

Also, the problem isn't that HTTPS is used without HTTP-layer
authentication.  The problem is that the browser stupidly performs a
request in one context that was given to it by a malicious site in
another context.  Suppose we have HTTP-layer authentication.  How does
that help the browser prevent that attack?  Having a referrer in the
HTTP-layer authentication would be no different than having a Referrer
header in the first place.

> for JavaScript form submission is a different beast.

I don't see a good alternative.  The problem is a confused deputy
problem.  We must either provide it with enough information that it
cannot be confused or we must have another party check that the deputy
is not doing something indicative of confusion.  If we stop thinking
about authentication and crypto for a minute, and think strictly about
the confused deputy problem in the abstract, what else can we do?

> already only do GET, forms can only do GET/POST, and XMLHttpRequest is

Note that same-origin restrictions are the sort of safety device that
I was talking about.  That doesn't work in the case of links embedded
in HTML because... well, because cross-domain links are exactly what
gives the web so much power, what distinguishes the web from all other
applications.

Now, we can't get rid of cross-domain links because we'd not want to
do that.  But we can add methods by which to constrain the kinds of
actions that a user agent will take when following cross-domain links.

For example, we could say that cross-domain links are followed outside
the context of logged-in sessions (i.e., without cookies or whatever
HTTP authentication methods and session material might have been used
otherwise), instantly stopping CSRF without breaking the vast majority
of cross-domain links.

Indeed, we might say that if a page wishes the browser to follow a
cross-domain reference *within* an authenticated session, then the
browser must first determine that the target site allows the remote
origin to do this.

> might also be difficult if protection is only offered client-side.

Well, the vast majority of legitimate cross-domain references are not
intended to be executed in the context of logged-in sessions.  If
that's true then we might well want to break all cross-domain
references that are intended to be executed in the context of
logged-in sessions.

Nico
--

---

From: Nico Williams <[email-masked]>
Date: Tue, 5 Jul 2011 17:51:39 -0500

> problems, a mechanism that isn't tied to cookies makes more sense to

No, the browser has to know not to follow cross-domain references in
any logged-in session context.  Whether the session be identified by
cookies or by something else (e.g., a session ID in HTTP
authentication) is irrelevant, as long as the browser knows to not use
any of it when following cross-domain references.

Nico
--

---

From: Tim <[email-masked]>
Date: Tue, 5 Jul 2011 16:55:39 -0700

> authenticate the deputy, but how to prevent its confusion.

Sure.

> would crypto at the HTTP layer prevent the deputy from getting

My proposal, in this context, was not to have the deputy try to
prevent it, but merely to include authenticated information about who
the requestor was so the server can decide if it is ok.

> that help the browser prevent that attack?  

It doesn't help the browser/deputy, it helps the server.

> Having a referrer in the

Right.  This isn't a major leap away from Referer.  It's just that
Referer is unreliable for privacy(/other?) reasons, so we need a more
reliable way to indicate to servers what the requesting origin was.

While we're going through the trouble of adding a variant of Referer,
why not also provide:

 A. Authenticity of this new origin mechanism, because in the past, it
    was possible to forge the Referer header with Flash*

 B. Additional privacy of this origin to protect the paranoid and
    improve adoption

* In security circles, it is still "best practice" to avoid using
  Referer as CSRF protection even though it should be relatively safe
  now that Flash isn't (as) broken.  I don't think anyone has
  conducted a comprehensive survey of other client-side scripting
  languages to see if it is possible to forge Referer cross-origin in
  some other way.

> If we stop thinking

Sure. 

So we can either have the deputy (browser) prevent CSRF, or we can
have it attach enough information to requests to allow the server to
handle it when it makes sense.

> actions that a user agent will take when following cross-domain links.

Exactly.  So if we try to have the deputy prevent CSRF, which is
admittedly attractive from a technical standpoint, then we have to
have some way to allow all old cross-origin request types that we
want.

This is where a new HTTP method could come in to play, as I've alluded
to.  Let browsers enforce a simple rule that ACTION(/PUT?) can only be
sent same-origin (or perhaps cross-origin if the server explicitly
allows it), and then have applications require ACTION be used on any
sensitive pages.

ADVANTAGES:
 - We don't worry about sending any extra info to servers about the
   origin, which avoids potential privacy issues.

 - Simpler implementation for web applications (don't need to validate
   one or more whitelisted origins with every request)

Or, using an Origin-like mechanism, we can enforce the fix on the
server.

ADVANTAGES:
 - Simpler implementation for browsers

 - Allows web applications to make more complex decisions about
   whether or not pages can be accessed cross-origin

Feel free to add to the list of advantages/disadvantages.

Clearly, taking the first approach means we don't need to talk about
this on http-auth. =)  I think if we're inclined to take the second,
then it makes sense to include Origin information in an authenticated
context to make the system more resilient.

> references that are intended to be executed in the context of

I don't think it is worth trying to mess with any existing
cross-origin behavior.  There would just be too much resistance,
legacy, and complexity which begets implementation flaws.  

cheers,
tim

---

From: Nico Williams <[email-masked]>
Date: Tue, 5 Jul 2011 19:10:39 -0500

> the requestor was so the server can decide if it is ok.

The fact that you'd have HTTP authentication (when that is in use)
transport this information does not mean that CSRF and authentication
are tightly coupled.  They're not.  The point of contact between CSRF
and authentication lies in whether a cross-domain reference can be
followed within the context of a logged-in session, and if so what is
conveyed to the server about the origin.  Assuming a sufficiently
abstracted interface to authentication the browser's job is to either
a) use a non-authenticated session/channel to follow the reference,
and/or b) to convey the origin of the reference to the server (whether
via an HTTP request header or as an input to whatever authentication
facility that might be in use).

If it wouldn't break much to insist that cross-domain references be
followed outside the context of authenticated sessions, then that
seems like the best option as the _default_ behavior for browsers,
with any switches to change that behavior resulting in the origin
always being sent to the server and/or the use of a critical facility
to decide whether to follow the reference in authenticated channel.

Nico
--

---

From: Nico Williams <[email-masked]>
Date: Tue, 5 Jul 2011 19:23:44 -0500

>    was possible to forge the Referer header with Flash*

So... every time some implementor screws up we need to introduce a new
thing instead of saying "just upgrade already"?

I don't see how this approach scales.

Also, given that most web sites don't use HTTP authentication, and
will continue not using it for years even if we agreed to a new HTTP
authentication method that solves all our problems, I don't think this
helps as much as any solution that the browser can implement locally
to either prevent CSRF altogether or help the server do so.

>  B. Additional privacy of this origin to protect the paranoid and

I don't see how this helps: the server gets to see the origin anyways.
 You could hash the origin, I suppose, and then the server could check
the hash against a table of trusted domainname hashes -- that would
help w.r.t privacy, but this could be done in HTTPS without any resort
to HTTP authentication.

> handle it when it makes sense.

Right.  Two types of solutions then.  The "don't use an authenticated
session to follow references from other origins" falls into the
locally-prevent-CSRF bucket.  The "send origin information" solution
falls into the give-the-server-more-info bucket.

> have some way to allow all old cross-origin request types that we

Right.

The way I would do that is to have the server provide a list of
trusted origins for cross-domain references.  This could be in the
form of a simple file at the top-level of the site, like robots.txt,
or it could be an HTTP verb to check whether an origin is trusted to
issue a given reference, OR, it could be a 'critical' HTTP request
extension to convey the origin in such a way that the server will not
execute the request unless the origin is allowed to have the deputy
issue that request.

I'm thinking that the only way to add critical HTTP extensions must be
through new verbs, which must be why you mention a new "ACTION" verb.
Would you agree that what you're looking for is a critical HTTP
extension?  It's so much what that extension does, as that it's
critical.

(Of course, the browser would have to use HTTPS if on-path active
attackers are an issue.  Attackers mount CSRF attacks only because
they are not on-path active attackers, but we should assume there will
be other active attackers on the wire.)

Nico
--

---

From: Tim <[email-masked]>
Date: Wed, 6 Jul 2011 08:41:22 -0700

> I don't see how this approach scales.

Where is it written in any standard, IETF, W3C, or otherwise, that
client-side technologies like Flash should not allow cross-origin
specification (forgery) of HTTP headers?

Origins for JavaScript don't match Origins for cookies.  Rules for
communication between Java and web servers are quite different from
rules for XMLHttpRequest.  The web is a mess.  It is incredibly
fragile with layers of bad assumptions piled higher and deeper.  

I think providing some integrity, via HTTP authentication, for
something like an Origin header is worth the expense, even though we
haven't yet thought of the next attack scenario to forge it.

Of course that all assumes that the best fix is by providing more
information to the server so the server can prevent CSRF.

> help w.r.t privacy, but this could be done in HTTPS without any resort

How does HTTPS help with privacy for Origins?  The privacy I'm talking
about here is hiding third-party Origins from the receiving server,
unless it is in a white list of domains the server trusts.

> execute the request unless the origin is allowed to have the deputy

Right, so the way I had envisioned it is that by default, a new HTTP
method would be restricted to same-origin unless something like CORS
was provided to allow additional origins to send it.

> extension?  It's so much what that extension does, as that it's

I honestly haven't put a lot of thought into alternative ways to
achieve the same thing.  A new HTTP method would work, for this
purpose, given that the current ways to send cross-origin requests are
pretty much restricted in browsers to GET and POST.  Adding a new,
restricted method is an easy way to provide backward compatibility.

However, a similar thing could be accomplished with a special header,
so long as it is well defined that such a header can only be sent
according to certain rules.  I kind of get the heebee geebees when
thinking about that though, given the frequency with which I find
various injection flaws in HTTP headers.  A new method would likely be
less susceptible to that.  

There is also this issue of Java applets, which I think can be used to
bypass any of these protections on sites that have multiple virtual
hosts.  (Correct me if I am wrong, but I believe Java allows arbitrary
control of a TCP stream back to the serving host's IP address, without
regard to the host name in the origin.)

This is where tying an origin into the authentication process provides
better protection.

> be other active attackers on the wire.)

Of course.

tim

---

From: Nico Williams <[email-masked]>
Date: Wed, 6 Jul 2011 11:28:54 -0500

> specification (forgery) of HTTP headers?

Some things aren't written down that should be.  Figuring out which
headers can be set by the script in cross-origin cases is going to be
tricky, unless we say none of them can be, or unless we wrap all those
headers with a prefix that the script can't avoid.

> haven't yet thought of the next attack scenario to forge it.

Sure, but the web is built on HTTPS + username&password form POSTing +
cookies.  HTTP authentication will not be deployed fast enough to make
a dent in CSRF.

> information to the server so the server can prevent CSRF.

Well, no, it's one approach.  The other approach is for the browser to
apply the local solution we've been discussing: do not follow
cross-origin references in the context of authenticated sessions
(which means: don't use HTTP auth and don't use cookies when following
cross-origin references).

> was provided to allow additional origins to send it.

Right, applying a CORS-like approach to cross-origin references in
HTML is what I had in mind as one option.  This requires no additional
HTTP methods.

What I have in mind is a new HTTP method(s) intended solely to add
criticality such that the client can be assured that the server will
not process the request unless the server understands some critical
element.  In this case the critical element would be the information
about the origin of the reference.  We'd actually have to wrap most
existing HTTP methods this way.

I still have no clue exactly what you had in mind regarding new HTTP methods :)

> restricted method is an easy way to provide backward compatibility.

I think it's criticality that you're looking for in your new HTTP
method idea.  Criticality is a well-understood concept (see RFC5280,
for an example, search for "critical").  It'd be useful to at least
agree that criticality is or is not of interest here.

> less susceptible to that.

The problem with criticality is that it's not enough to declare a new
protocol element to be critical if *existing* implementations would
ignore it.  In HTTP the only critical protocol elements that I know of
is the HTTP method, and the authentication method (since the web
server will fail to complete authentication for an auth method it
doesn't support).  But I'm not re-reading the HTTP spec as I write
this, so I might have missed another element.  Perhaps this is why
you're focused on HTTP auth and/or HTTP methods as a solution to CSRF,
because you understood the need for criticality and how to get it
without knowing what to call it?

If we call this out explicitly then we can see what to do: leverage
*existing* critical elements of HTTP.  Right?

Nico
--

---

From: Tim <[email-masked]>
Date: Sun, 10 Jul 2011 13:20:35 -0700

Hi Nico,

Sorry for the slow reply.  Busy busy.

> cookies.  HTTP authentication will not be deployed fast enough to make

Well, let's see, we've know about CSRF for about a decade.  We've
known about XSS for over a decade.  Security people have been trying
to help people fix both for almost that long, and yet 3/4s of
applications I look at are vulnerable to CSRF.  Maybe 2/3rds have XSS.

Offering a drop-in solution to CSRF would create a strong incentive to
adopt a new security technology.

> HTML is what I had in mind as one option.  This requires no additional

But you can't just go back and add a restriction on existing uses of
cross-origin access.  Consistent deployment, for the purposes of
security, will just be unworkable.

Examples of this approach for "upgrading" security that have fallen
flat on their face:
 - Secure cookie flag

 - STARTTLS

 - Multiple HTTP authentication methods offered at once

All are vulnerable to downgrade attacks or are frequently not used
because the desired support for legacy usage.

We would be much better off, from a security standpoint, to offer a
new mode for making requests that is restricted by default.

> ignore it.  

Right, very good point.

> In HTTP the only critical protocol elements that I know of
> doesn't support).  

Unfortunately, many web applications don't actually check the request
method, even though it may be considered critical (or equivalent) in
the RFC.  But still, it is easy enough to identify the lack of method
validation and adding that validation is for web developers than
asking them to implement crypto token systems.

> But I'm not re-reading the HTTP spec as I write

Well, I guess I was mostly focused on the method since that fits the
idea of what we're doing.  Originally, POST requests were intended for
sending information to servers whereas GET were supposed to be
strictly for retrieving.  This distinction has become fully blurred in
modern web applications, partly because the HTTP definitions of these
weren't strict or enforced.  Also, this probably came about because
GET and POST offer different modes of sending data to the server that
you may want for different use cases: GET is limited in data size, but
bookmarkable; POST is useful even without state change if you don't
want users to bookmark parameters, etc.

So in my mind, what we need is a narrower definition of what POST
allows, with the original implied state-change transaction, but
restricted to specific sending origins.  

> *existing* critical elements of HTTP.  Right?

Perhaps another way to attempt to achieve criticality would be to
define a separate content-type of parameters in an ACTION(/PUT) body.
Web servers that don't understand the method might be tempted to treat
those requests as POSTs, and but then would fail if the body isn't
formatted in a way they expect.  In any case, the body content-type
does seem to be a critical element. 

tim

---

From: Nico Williams <[email-masked]>
Date: Mon, 11 Jul 2011 11:37:50 -0500

> adopt a new security technology.

Look, I've nothing against what you propose as one alternative.  But
your proposal requires changes all around.  Whereas one of the
counter-proposals I made to yours requires only browser changes, not
changes to how every site does authentication, nor any change to user
credentials.  This is important because changes to how we do
authentication will take a long time to push out, whereas changes to
browsers are much speedier thanks to automatic updates.  Sure, some
stubborn users (and IT departments who have legacy reasons for staying
with old browsers) take a long time to upgrade, but they wouldn't be
helped by your proposal either.

> security, will just be unworkable.

I think you can.  The cross-origin restriction can be implemented in
the browser or the services, and all it means is that cross-origin
references that should be disallowed can only be evaluated outside the
context of any authenticated sessions (i.e., anonymously).  What's the
problem with that?

> new mode for making requests that is restricted by default.

Which will take forever and a half to deploy.

>> protocol element to be critical if *existing* implementations would

It's nothing new...  We've faced this problem in Kerberos and PKIX
before (and SSHv2, and...).  It's important to always leave some sort
of critical field somewhere, and preferably in all directions.

> asking them to implement crypto token systems.

Surely web servers and applications do not treat GET and POST as
synonyms -- otherwise the offenders would be famous for the offense.
Also, presumably all web servers and applications fail to handle
unknown HTTP methods as synonyms for some other existing method.  If
some small number of servers get this wrong, no sweat, but if a huge
proportion of them get this wrong then there's nothing we can do on
this end.

> [...]

I'd like you to be more specific.  Were you or were you not,
consciously or otherwise, looking for some HTTP criticality mechanism?
 Or, now that we have the criticality concept clarified, is this what
you're looking for?

> define a separate content-type of parameters in an ACTION(/PUT) body.

Ah, good one!  I'd prefer a new method though, as otherwise we'd begin
to explode the set of content-types, and I don't want to go down that
road without a really good reason.

> does seem to be a critical element.

We could use both, in a pinch.  I seriously doubt there exist web
servers that mishandle unknown HTTP methods.

Nico
--

---

From: Tim <[email-masked]>
Date: Tue, 12 Jul 2011 20:54:20 -0700

Nico,

> context of any authenticated sessions (i.e., anonymously).  What's the

The way I understand what you are proposing (and I could be mistaken),
will likely cause existing applications to break.  Web application
developers abuse HTTP behavior in all *kinds* ways.

Let me just assert this:  If you propose a change to existing
cross-origin behavior for browsers which:

A. Breaks even a small percentage of existing applications.

B. Requires any changes at all for non-broken applications to benefit
   from the new security protections

Then you're in a catch-22 and it will never be deployed.  Application
developers won't bother to implement it until browsers support it and
browsers won't support it until very few sites will break and lots of
sites will benefit from it. This may or may not be what you're
proposing. 

>From what you are saying, I have a problem with: "can only be
evaluated outside the context of any authenticated sessions".  The
problem is, browsers don't currently have a way to know what an
authenticated session is.  Cookies are used for many things, some
intended for cross-origin use.  If you're intending your statement to
apply only in HTTP authentication scenarios, then maybe that is
workable...

> Which will take forever and a half to deploy.

I disagree.  All that it takes is for browsers to add support for the
new restricted method (the hard part).  Browsers wouldn't even need to
implement CORS right away.  This breaks nothing.  Then the difficulty
of fixing CSRF for developers becomes trivial: change a few HTML pages
(method="POST" -> method="ACTION") and validate that this method is
used server-side for sensitive pages.  This is far easier than making
developers invent a cryptographic protocol to protect themselves and
it is even easier than expecting them to correctly parse an origin
header (you'd be surprised at how easily they could screw this up).

Note that for a significant portion of sensitive applications that I
personally test (over half of them, at least), something like CORS for
the new method wouldn't be a requirement.  The details of an optional
permissive mechanism could be worked out later.

> synonyms -- otherwise the offenders would be famous for the offense.

Yes, actually they do.  The only difference being where they draw
parameters from.  Most modern web frameworks merge the variable name
space for each of these request types (e.g. POST parameters and URL
parameters in the same request get merged into one name space).
They've been doing this for a decade at least.  In most applications I
test, one can easily convert a POST request in to a GET request and
vice versa.  If parameters are in the URL in both cases, there's
effectively no difference in how they are handled.

> unknown HTTP methods as synonyms for some other existing method.  

Most application servers do check to make sure it is at least a GET,
POST, or HEAD, etc, but some popular frameworks don't even bother to
do that.

> If

Agreed, we can't account for application servers that don't even
bother to enforce a set of valid methods.  In the case of the ACTION
approach, it doesn't matter either way.  When a developer is ready to
use it, they add it both in the pages that initiate requests and
validate it upon receiving a request.

>  Or, now that we have the criticality concept clarified, is this what

I suppose so, but I won't testify to it, because I'm not sure how
critical the method really is, based on real-world server
implementations.

It must be an element that browser can easily recognize and then
initiate the cross-origin checking logic.  This is most easily added
to an element that is already sent in every request and can be
controlled by developers initiating requests.  

Requiring it to be some special header that is added by developers in
XHR requests is restrictive, since classic HTML can't benefit from it.

> road without a really good reason.

Yeah, I agree.  

Here's another alternative that is effectively uses a critical
element: 

Change URL syntax.  Add a prefix/suffix/something to URL syntax that
indicates to browsers that the request should follow restricted rules.
Either a prefix before the first "/" that is pretty distinguishable
(consider the special OPTION * HTTP/... syntax) or something similar
to the "#..." syntax, but is instead carried on to the recipient. 
This might be harder to deploy though, since many web servers might
validate URL syntax even more carefully than methods, depending on how
you add the new syntax.  In the web servers I know, methods are
something that can be flexibly configured. A lot of applications are
already using every ASCII character in the book already in their URLs,
so backward compatibility would be more of an issue if it is used at
the end.

Just trying to brainstorm other ways to support even the most basic
use cases (HTML forms).

> servers that mishandle unknown HTTP methods.

Hahaha, if you only knew...

But it doesn't really matter, since those sites/applications that do
mishandle a new method right now are either vulnerable to CSRF now
(and will be with a new method that isn't validated) or are protected
by crypto cookies or referrer checks (and will continue to be
protected if a new method isn't validated).

tim

---

From: Nico Williams <[email-masked]>
Date: Fri, 15 Jul 2011 18:34:59 -0500

> developers abuse HTTP behavior in all *kinds* ways.

I get that, but this can be addressed in ways which are less expensive
than yours.  Namely, via something like CORS.

That said, I do think we're going to have to deploy new authentication
schemes so as to defeat phishing, so maybe I'm barking up the wrong
tree.  I just think that it will take a long time to migrate to new
authentication methods but it should be possible to do something about
CSRF sooner.  Does NoScript do anything about this?  It does turn
cross-site POSTs into data-less GETs.  I wonder if it could be made to
load cross-site images without cookies -- that would allow us to test
this.

Incidentally, I do run with NoScript's CSS/ABE protection enabled and
I've yet to find a site that breaks because of it.  I suspect, but
can't prove, that nothing much depends on cross-site image references
being loaded in the context of authenticated sessions.

> new restricted method (the hard part).  Browsers wouldn't even need to

Oh no, that's not the hard part.  The hard part is getting user
credentials migrated.

Or are you simply talking about a new method that doesn't provide
strong user authentication, just strong request/session binding?  That
is, the OAuth hammer HMAC draft?  Ah, then I think I understand where
you're coming from.  And yes, that might not be so hard to deploy.

Nico
--

---

From: Tim <[email-masked]>
Date: Fri, 15 Jul 2011 16:42:45 -0700

> you're coming from.  And yes, that might not be so hard to deploy.

Correct.  Almost all of my recent blathering has been solely about
using a new method to prevent CSRF.  Nothing to do with HTTP auth.
Initially I proposed the HTTP auth-based (basically just an
integrity-protected Origin header) and alluded to this other idea of
an HTTP method.  

Then you took me down the path of browser-based validation which is in
line with a new HTTP method and doesn't involve authentication.

Does that clarify the last few messages?
tim

---

From: Nico Williams <[email-masked]>
Date: Fri, 15 Jul 2011 19:09:01 -0500

> Does that clarify the last few messages?

Sure does.  It should also clarify my earlier skepticism :)

I'd still like at least a way to set *my* browser to never load
x-origin references with cookies (or any other form of user
authentication) unless the one site specifically allows the other to
make x-site references.  This sounds like an interesting possibility
for NoScript.

Nico
--

---

From: Tim <[email-masked]>
Date: Fri, 15 Jul 2011 17:17:15 -0700

>From a standards perspective, that idea sounds reasonable way to
mitigate CSRF with HTTP authentication.  Perhaps it could be slipped
into a new HTTP Auth spec.  

I'm not sure it would be so easy with cookies. Maybe it's just because
I haven't put much thought into it.  At this point I think trying to
fix that mode of "authentication" is a lost cause.

Cheers,
tim

---

From: Nico Williams <[email-masked]>
Date: Fri, 15 Jul 2011 19:33:19 -0500

> into a new HTTP Auth spec.

It's not that different from what you propose.  You propose
server-side control.  Also having a client-side control would be a
useful thing to do for at least power users (cue complaints about
complexity, yet who here doesn't use NoScript, complex as it is?).

> fix that mode of "authentication" is a lost cause.

Why not?  It's a small change to the browser (compared to everything
else we're talking about).  I'm not trying to fix the use of cookies.
Besides, I think cookies can work fine *if* you pin certs and are
careful not to use "secure" cookies outside TLS [with confidentiality
protection], but as with any other form of authentication you'll want
to do something about CSRF.

---

From: Tim <[email-masked]>
Date: Fri, 15 Jul 2011 19:47:17 -0700

> to do something about CSRF.

Because I don't think it would get traction.  Browsers can't
distinguish between cookies used in non-authentication scenarios and
scenarios where they are used in authentication.  The
non-authentication scenario has business drivers for use in
cross-domain settings.  Forcing the world to add a CORS rule to
satisfy a backward-incompatible browser change doesn't seem like it
could work.  

But then, I don't work in advertising or in areas where cookies are
used for non-authentication scenarios, so I don't really know what the
issues would be. 

Also, any encouragement of people to stick with cookies for
authentication is encouragement to stay insecure.  Few people,
including security consultants, realize just how easy it is to hijack
sessions if you can conduct a MitM attack against HTTPS+cookies.
Forget to set the secure flag?  Session can be hijacked.  Forget to
refresh session cookies during login?  Session can be hijacked.  This
is true even if you don't even provide an HTTP interface and assume
users/browsers properly validate certificates.  

Between just these two common flaws, I would bet close to 40-50% of
sites I personally test are vulnerable to MitM.  In these cases, why
bother running SSL?  These are just two of many flaws an attacker has
to work with.

tim

---

From: Nico Williams <[email-masked]>
Date: Sat, 16 Jul 2011 00:37:58 -0500

Ah, I'll admit I tend to not be conscious of advertising.