[cap-talk] Security considerations for cookies
Adam Barth
w3c at adambarth.com
Mon Feb 15 07:35:59 PST 2010
On Mon, Feb 15, 2010 at 6:05 AM, Mark Seaborn <mseaborn at chromium.org> wrote:
> On Sun, Feb 14, 2010 at 6:34 PM, Adam Barth <w3c at adambarth.com> wrote:
>> I think it's better to be slightly general here. We're writing the
>> document for the long term. Web-keys are one instance of the general
>> concept, but they might seem archaic to a reader ten years from now if
>> some other URL capability scheme catches on.
>
> Fair enough. You do mention secrets-in-URLs later in the document; maybe
> this should go in "general recommendations" too, if HTTP auth and client
> certs are mentioned in this section.
I've actually removed HTTP auth and client certs from the earlier
section because they seemed to be causing more confusion than good.
>> If the UA issues a single HTTP request, an active network attacker can
>> spoof an HTTP redirect response and cause the UA to generate an HTTP
>> request to the server. Now, if the user agent is configured to use
>> Strict-Transport-Security for that host, there is some hope. :)
>
> Thanks for explaining. Is there a name for this attack? "Cookie
> overwriting" sounds appropriate (and you use this term in your paper), but
> Googling for this term doesn't produce many references.
I don't know of a good name. Informally, we've been referring to it
as "cookie forcing."
> OK, so there are two kinds of cookie overwriting attack:
> * cookie overwriting by hijacking an unencrypted HTTP connection
> * cookie overwriting by "login CSRF"
> Is there a succinct term for the first that distinguishes it from the
> second?
Well, there are more actually. For example, that two sibling domains
can overwrite each others cookies is another form. Really, these are
just integrity failures in the cookie protocol.
> Can't these attacks be addressed by the usual means of including a suitably
> unguessable secret in the URL or POST parameter (which can be checked
> against the cookie if you want to protect against URL leaks)?
Nope. Recall, that we're worried about an attack who uses these
integrity failures to transplant cookies from his browser to the
user's browser. He can just as easily transplant the "unguessable"
secret he receives in his browser to the user's browser in the URL or
POST parameters.
> My initial reaction was that overwriting-by-hijacking is not a CSRF or a
> confused deputy attack. Normally in CSRF, Alice (an attacker) makes a
> request and Bob's ambient credentials are applied. In the attacks above,
> Alice arranges it so that when Bob makes a request, Alice's credentials are
> applied.
Indeed, it is not a CSRF because there is no cross-site request that
is being forged. The consequences are similar to login CSRF, which is
why I mentioned it.
> Or to look at it a different way, the attack is enabled by Bob's failure to
> authenticate (or at least fully specify) the object he is talking to. Bob
> thinks he's talking to (url, bob_cookie), but he's actually talking to (url,
> alice_cookie).
I don't think that's correct. The attack is cause by the inability of
the server to bind to the user's browser. That's why URL tokens don't
help: they don't binding to the browser any better than cookies in
this threat model.
> On further reflection, CSRF is different from the classical confused deputy
> compiler example:
> * In the compiler example, the attacker fully designates an object using a
> guessable filename in a global namespace. More fully designating the object
> does not solve the problem.
> * In CSRF, the attacker specifies an object using a guessable name that is
> relative to an account. More fully designating the object (using
> unguessable strings) is part of the fix. (I am assuming that an object is
> something that is account-specific here, which is not always true.)
>
> Login CSRF consists of two steps:
> * The attacker sends the login HTTP request.
> * The innocent page uses the resulting overwritten cookies.
> Which part is the CSRF? The first step looks like a CSRF, but since it's
> not using any credentials in the request, I suppose it is abusing the HTTP
> server's ambient authority to overwrite the browser's cookies.
The first part is CSRF. Quite literally, the attacker is forging a
cross-site request to the login page. You are correct that it's a
CSRF attack that doesn't involve any credentials.
>> Web-keys have the same login CSRF problems because the attacker can
>> force the user's browser to navigate to the attacker's web-key. Now,
>> the user might not notice that they're interacting with the server
>> under the attacker's authority.
>
> This attack can only work at a coarser granularity than login CSRF, though,
> can't it? The attack can only replace the whole page, whereas login CSRF
> can violate the integrity of individual parts of the page during the page's
> lifetime.
Or maybe it works at a finer grain because I can replace pages in one
tab but leave pages in other tabs unmolested. In any case, the
granularity of the attack doesn't matter. The attack is still
problematic.
> I would call this attack a kind of spoofing, rather than CSRF. Rather than
> one site spoofing another, it can be one account or page spoofing another on
> the same site. Tyler's Petname toolbar would not help in this case. Maybe
> this can be addressed by petnames that are finer-grained than a site, which
> might require sites' co-operation to establish.
You're welcome to call the attack whatever you like, but it is, quite
literally, a CSRF attack. Namely, the attacker is forging a
cross-site request containing a web-key (his own).
Instead of thinking about CSRF in terms of ambient authority, it's
more helpful to think about them in terms of the integrity failures
that arise from the ability of one web site to generate HTTP requests
to other web sites.
>> >> >> User agents can mitigate this issue to some degree by
>> >> >> providing APIs for suppressing the Cookie header on outgoing
>> >> >> requests.
>
> My problem with this statement is the agency it implies for user agents (no
> pun intended!). There are some security issues an individual user agent can
> address on its own, but this is not one of them.
I guess we can say, more precisely, that the agency lies with the user
agent implementors (to provide the APIs) and the application
programmers (to use the APIs).
>> That's the exact argument I've been making in the CORS/UMP discussion
>> in W3C WebApps, but MarkM and Tyler don't appear to agree with that
>> point of view. Do you have a proposal for what we could say at that
>> point the draft that would be less vague?
>
> You mean like in
> http://lists.w3.org/Archives/Public/public-webapps/2009OctDec/0155.html?
Possibly. There's been a lot of messages on that topic. :)
> I'd still say that the best way to ensure that servers disregard the
> presence or absence of cookies is to ensure that new APIs don't send
> cookies.
Perhaps.
> How about: "Servers can mitigate this issue by disregarding the presence or
> absence of ambiently-provided credentials (including cookies) in requests
> and by using other authorising information instead. Standards bodies [or
> user agent implementors] can encourage this behaviour by providing user
> agent APIs that do not send ambient credentials in requests."
I've just removed the sentence. The more we clean it up, the more it
becomes like the third paragraph in that subsection, which does a
better job of explaining what's going on anyway. Plus, it makes more
sense to present the solution after explain the problem fully (which
we do in paragraph 2).
>> >> I've changed this to the following:
>> >>
>> >> [[
>> >> Servers SHOULD encrypt and sign their cookies when transmitting
>> >> them to the user agent (even when sending the cookies over a secure
>> >> channel).
>> >> ]]
>> >
>> > It would be better to say that cookies should consist of
>> > encrypted/signed
>> > data, or "servers should use cookies that are encrypted and signed".
>>
>> This text seems to be the same as the above, but in the passive voice.
>
> Not exactly the same, because the passive voice adds ambiguity. :-)
>
> C = encrypt(D, key)
>
> C is the cookie.
> D is not a cookie.
> The server encrypts D.
> The server does not encrypt C.
> D is encrypted (that is, D gets encrypted, but D does not consist of
> encrypted data).
> C is encrypted (that is, C consists of encrypted data, but C does not get
> encrypted).
>
> This is my interpretation, anyhow. :-)
This issue should be fixed now that we refer to encrypting the
"content" of the cookie. We can then take D to be the content of the
cookie (note that we take C to the be the "value" of the cookie
earlier in the document).
>> I presume you mean <http://wiki.erights.org/wiki/Swiss_number>?
>
> Yes.
>
>> Indeed, these do not require encryption or signatures.
>
> You could change the text to cover this case by saying "Cookies should not
> be meaningful to any party other than the server. The server should ensure
> that cookies can only be interpreted by the server by either:
> * using randomly-generated numbers that are looked up in a table on the
> server [Swiss numbers], or
> * encrypting and signing potentially-sensitive data to yield cookies."
I'm not sure this distinction is worth making. I'd rather folks just
encrypted and signed all their cookies. It's a SHOULD-level
requirement, so folks don't need to follow it if they understand the
consequences of what they're doing.
Adam
More information about the cap-talk
mailing list