Re: [OAUTH-WG] Auth Code Swap Attack

Eran Hammer-Lahav <> Thu, 18 August 2011 07:16 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 43B5311E8084 for <>; Thu, 18 Aug 2011 00:16:01 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.557
X-Spam-Status: No, score=-2.557 tagged_above=-999 required=5 tests=[AWL=0.041, BAYES_00=-2.599, HTML_MESSAGE=0.001]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id c1I4-Fhb35T3 for <>; Thu, 18 Aug 2011 00:15:43 -0700 (PDT)
Received: from ( []) by (Postfix) with SMTP id 7937721F84CE for <>; Thu, 18 Aug 2011 00:15:40 -0700 (PDT)
Received: (qmail 19279 invoked from network); 18 Aug 2011 07:16:32 -0000
Received: from unknown (HELO ( by with SMTP; 18 Aug 2011 07:16:31 -0000
Received: from P3PW5EX1MB01.EX1.SECURESERVER.NET ([]) by P3PW5EX1HT004.EX1.SECURESERVER.NET ([]) with mapi; Thu, 18 Aug 2011 00:16:31 -0700
From: Eran Hammer-Lahav <>
To: Phil Hunt <>
Date: Thu, 18 Aug 2011 00:15:15 -0700
Thread-Topic: [OAUTH-WG] Auth Code Swap Attack
Thread-Index: AcxdcdaZvjxF67yXSiK2lQA5SNJGTwAAuDng
Message-ID: <90C41DD21FB7C64BB94121FBBC2E72345029DFA964@P3PW5EX1MB01.EX1.SECURESERVER.NET>
References: <> <> <90C41DD21FB7C64BB94121FBBC2E7234502498CE8D@P3PW5EX1MB01.EX1.SECURESERVER.NET> <90C41DD21FB7C64BB94121FBBC2E72345029DFA961@P3PW5EX1MB01.EX1.SECURESERVER.NET> <>
In-Reply-To: <>
Accept-Language: en-US
Content-Language: en-US
acceptlanguage: en-US
Content-Type: multipart/alternative; boundary="_000_90C41DD21FB7C64BB94121FBBC2E72345029DFA964P3PW5EX1MB01E_"
MIME-Version: 1.0
Cc: "OAuth WG (" <>
Subject: Re: [OAUTH-WG] Auth Code Swap Attack
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: OAUTH WG <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Thu, 18 Aug 2011 07:16:02 -0000

There was no argument made. You described a CSRF attack scenario which carries the exact same risk and uses the exact same solution as the CSRF attack already present in the specification. Then jumped from there to a new normative requirement. I have not seen any argument to justify the new MUST requirement - if I have missed it, please point me in the right direction.

Also, -20 has no such inconsistencies. It is OPTIONAL in one place and RECOMMENDED in the other.

However, -20 does not *require* CSRF protection which put it at odds with how we address every other attack vector, so we are in full agreement that CSRF prevention is a MUST. My text fixes that in a manner consistent with how you and the other security consideration section drafters approached many of the other sections (by requiring a solution but not limiting developers to a particular one).

There are two open issues:

- the quality of the prose (I agree that Bill's text is a good new starting point), and

- whether we should dictate to developers the parameter name (and location) of the CSRF artifact.

If we decide that we should mandate such a parameter, we then need to decide if 'state' is the right place and if it is, find a new way to describe it because using it for CSRF is a relative new use case for the parameter (which still have all the previous use cases).


From: Phil Hunt []
Sent: Wednesday, August 17, 2011 11:41 PM
To: Eran Hammer-Lahav
Cc: OAuth WG (
Subject: Re: [OAUTH-WG] Auth Code Swap Attack

I felt the argument provided was persuasive and that the current spec leaves implementers open to attack. I get concerned when the core spec says "OPTIONAL" for state and then Security Considerations says REQUIRED. The inconsistency seemed to be a flaw in draft 20.

As to your comment about a tie vote, all that shows is a lack of consensus. Clearly we need to keep working on some more proposals.

I think it is reasonable to determine whether MUST is appropriate in all cases. I agree with what you said earlier, we should have more specific language other then "of sufficient complexity" to describe the value of the state parameter.

I saw a proposal by William Mills that I would like to see more discussion on.



On 2011-08-17, at 11:04 PM, Eran Hammer-Lahav wrote:

I would like to hear from the other 3 authors of the proposed change about their reasons for changing the use of 'state' from recommended to required for CSRF prevention. It would also help moving this issue forward if the 4 authors can provide answers or clarifications on the issues raised below.

Assuming we can count all 4 authors are in favor of making the change, I believe we have a tie (4:4) and therefore no consensus for making it (as of this point). However, we did identify issues with the section's language and clarity which we should address either way.

To clarify - I am not proposing we close this issue just yet.


From:<> []<mailto:[]> On Behalf Of Eran Hammer-Lahav
Sent: Monday, August 15, 2011 9:35 AM
To: OAuth WG (<>)
Subject: Re: [OAUTH-WG] Auth Code Swap Attack

To demonstrate why making state required as proposed isn't very helpful, here is an incomplete list of other requirements needed to make an effective CSRF:

* State value must not be empty (a common bug in many implementations using simple value comparison).

* 'Non-guessable' isn't sufficient as most developers will simply use a hash of the session cookie, with or without salt which isn't sufficient. We use "cannot be generated, modified, or guessed to produce valid values" elsewhere in the document, but this is much easier to get right for access tokens and refresh tokens than CSRF tokens which are often just some algorithm on top of the session cookie.

* State CSRF value should be short-lived or based on a short-lived session cookie to prevent the use of a leaked state value in multiple attacks on the same user session once the leak is no longer viable.

In addition, this is not what "state" was originally intended for. If the working group decides to mandate a CSRF parameter, it should probably be a new parameter with a more appropriate name (e.g. 'csrf'). By forcing clients to use "state" for this purpose, developers will need to use dynamic queries for other state information which further reduces the security of the protocol (as the draft recommends not using dynamic callback query components). Encoding both CSRF tokens and other state information can be non-intuitive or complicated for some developers/platforms.


From: Eran Hammer-Lahav
Sent: Friday, August 12, 2011 2:53 PM
To: Anthony Nadalin; OAuth WG (<>)
Subject: Re: [OAUTH-WG] Auth Code Swap Attack

This is really just a flavor of CSRF attacks. I have no objections to better documenting it (though I feel the current text is already sufficient), but we can't realistically expect to identify and close every possible browser-based attack. A new one is invented every other week.

The problem with this text is that developers who do no understand CSRF attacks are not likely to implement it correctly with this information. Those who understand it do not need the extra verbiage which is more confusing than helpful.

As for the new requirements, they are insufficient to actually accomplish what the authors propose without additional requirements on state local storage and verification to complete the flow. Also, the proposed text needs clarifications as noted below.

From: Anthony Nadalin <<>>
Date: Fri, 12 Aug 2011 12:06:36 -0700
To: "OAuth WG (<>)" <<>>
Subject: [OAUTH-WG] Auth Code Swap Attack

Recommended Changes to draft-ietf-oauth-v2

In section 4, request options (e.g. 4.1.1) featuring "state" should change from:

OPTIONAL. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client.


REQUIRED. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The encoded value SHOULD enable the client application to determine the user-context that was active at the time of the  request (see section 10.12). The value MUST NOT be guessable or predictable, and MUST be kept confidential.

Making the parameter required without making its usage required (I.e. "value SHOULD enable") accomplishes nothing. Also, what does "MUST be kept confidential" mean? Confidential from what? Why specify an "encoded value"?

Section 10.12 Cross-Site Request Forgery

Change to:

Cross-site request forgery (CSRF) is a web-based attack whereby HTTP requests are transmitted from the user-agent of an end-user the server trusts or has authenticated. CSRF attacks enable the attacker to intermix the attacker's security context with that of the resource owner resulting in a compromise of either the resource server or of the client application itself. In the OAuth context, such attacks allow an attacker to inject their own authorization code or access token into a client, which can result in the client using an access token associated with the attacker's account rather than the victim's. Depending on the nature of the client and the protected resources, this can have undesirable and damaging effects.

In order to prevent such attacks, the client application MUST encode a non-guessable, confidential end-user artifact and submit as the "state" parameter to authorization and access token requests to the authorization server. The client MUST keep the state value in a location accessible only by the client or the user-agent (i.e., protected by same-origin policy), for example, using a DOM variable, HTTP cookie, or HTML5 client-side storage.

The authorization server includes the value of the "state" parameter when redirecting the user-agent back to the client. Upon receiving a redirect, the client application MUST confirm that returned value of "state" corresponds to the state value of the user-agent's user session. If the end-user session represents an authenticated user-identity, the client MUST ensure that the user-identity has NOT changed.

The above text uses 'user-context' and this 'user-identity'. Neither term is defined.

OAuth mailing list<>