In line !

> 22 feb 2016 kl. 05:08 skrev John Bradley <ve7...@ve7jtb.com>:
> 
>> On Feb 22, 2016, at 9:22 AM, Nat Sakimura <n-sakim...@nri.co.jp> wrote:
>> 
>> The risk impact of [case2] is more OAuth specific. The token is stolen as 
>> the token is going to be sent to a rogue resource, and the resource can use 
>> that to obtain the resource that was supposed to be only available to the 
>> proper client.
>> 
>> The risk impact of [case3] is the most grave among these three. Now the 
>> attacker can create his own client that impersonates the compromised client.
>> 
>> OAuth-mix-up
>> ---------------------------
>> OAuth-mix-up draft gives one way of addressing [case2] by introducing a new 
>> concept of “issuer” and “discovery” to RFC6749. It also returns client_id 
>> and verifies it in 4.2, but if the BadAS has assigned a same client_id to 
>> the client, it does not help.
> 
> Client_id are not guaranteed to be unique.  They need to be name spaced by 
> the AS.   In OAuth currently we have no name for the AS this makes that 
> difficult, the client can use the authorization endpoint URI, but that logic 
> may well break in multi tenant situations.   Having a clear issuer string 
> makes it easier for the client.
I stumbled over exactly this point when I made my implementation follow the 
Mix-Up draft.
If not discovery is involved I think an AS has to have a name which is 
different from the endpoint URIs.

>> One of the issue with this approach is that the central notion of “issuer” 
>> is new to the existing servers and clients. The verification rule in 4.1 
>> states “Compare the issuer URL for the authorization server that the client 
>> received when it registered at the authorization server”, but in most 
>> existing pure OAuth cases, there is no such thing, so you cannot compare. 
>> This means that you would have to re-register, and if you are doing that, 
>> the per-AS redirect_uri seems to be a much simpler solution.
> 
> The client developers I have talked to really hate per AS redirect URI as 
> being too awkward for deployments.

I on the other hand found it quite easy to do per AS redirect URIs, so it might 
well be implementation
dependent rather then contextual.

>> 
>> Per AS Redirect URI
>> --------------------------------
>> This does not involve wire protocol changes. It just adds requirements on 
>> the redirect uri. This by far is the simplest solution for [case2] (and 
>> [case1]), IMHO.
>> 
>> Again, it is not a general framework for finding out tainted communication, 
>> so it may have other holes.
> 
> This is probably the hardest for the client developer and for the deployer.  
> Yes it is simplest from a spec point of view.
> We need more developer feedback on this.

As I said above I found this quite simple to implement.

>> (Extended) PKCE
>> ---------------------------------
>> To begin with, it works only with code flow. There has to be something else 
>> to deal with implicit flow.
>> 
>> PKCE binds the authorization request/response to the token request.
>> If used with a confidential client, it seems to mitigate the vulnerability.
>> John points out that it is not the case. I must be missing something here… 
>> but my logic goes like:
>> 
>> 
>> 1.     The good client creates code_challenge-v and 
>> code_verifier-v=S256(code_challenge-v) and sends the client_id-v + 
>> code_challenge-v + state to the BadAS Authz EP.
>> 2.     BadAS as a client prepares a code_verifier-b and 
>> code_challenge-b=S256(code_verifer-b).
>> 3.     BadAS redirects to GoodAS with the client_id-v + code_challenge-b + 
>> state-v.
>> 4.     GoodAS stores the code_challenge-b.
>> 5.     GoodAS returns code-v + state-v to the client’s redirect uri.
>> 6.     The client finds the AS from the state and sends code-v + 
>> code_verifier-v + secret-b to the BadAS token endpoint. Now, code-v and 
>> code_verifer-v is phished.
>> 
>> Now the attacker tries to use the code-v and code_verifier-v.
>> 
>> ### Case A:
>> 7.     The BadAS as a client sends client_id-v + … but he does not have 
>> client secret for the good client, so it fails.
>> 
>> ### Case B:
>> 8.     The BadAS as a client sends client_id-b + code-v + code_verifier-b + 
>> secret-b etc. to GoodAS.
>> 9.     GoodAS verifies the code_verifier-b is associated with code-v, but 
>> that code-v is not associated with client_id-b, so the token request fails.
>> 
>> ### Case C: cut-n-paste
>> 10.  The attacker launches cut-n-paste attack by replacing the code-b with 
>> code-v.
>> 11.  The verifiers does not match, so fails.
>> 
>> Please let me know what I am missing.
> 
> In a step 0 the attacker has the good client create another request in the 
> attackers user agent to get state-0 and code_challange-0
> 
> Step 2 is not required.
> Step 3 Bad AS redirects to good AS with client_id_v + state-v + 
> code_challenge-0
> Step 4 GoodAS stores code_challenge-0
> Step 5 GoodAS returns code-v + state-v to the clients redirect_uri
> Step 6 The client finds the AS from the state and sends code-v + 
> code_verifier-v + secret-b to the BadAS token endpoint. Now, code-v and 
> code_verifer-v is phished.
> 
> Case C1 :  cut and paste
> 10.  The attacker launches cut-n-paste attack by inserting code-v into a 
> response using state-0
> 11. The client sends code-v and based on state-0 it sends code_verifyer-0 to 
> the good AS token endpoint.
> 12. The GoodAS verifies that code-verifyer-0 is correct for code_challange-0 
> that it bound to code in step 4
> 13. The GoodAS receives RT + AT.
> 14. The attacker has now used the client to bind the users resource to it’s 
> account and is transferring money or looking at your data.
> 
> This could be 3rd party financial app like Mint as an example or photos or 
> any other PII that could then be used to escalate identity theft.
> 
> This variation of the attack combining cut and paste with confused client was 
> not mentioned in the research papers.
> 
> I found it looking to see if PKCE could be used to mitigate the confused 
> client attack.
> 
> As I mentioned in a response to William, while the current PKCE Challenge 
> methods only make the attack harder by forcing the attacker to get the client 
> to make a step 0 request to get a code_challenge to use in the request,  we 
> could define a new challenge method that would be effective.
> 
> That would remove the need to have a separate mechanism to prevent cut and 
> paste.
> 
> The problem is that the PKCE challenge is independent of state so becomes 
> vulnerable to the confused client.
> 
> What we would need to do is include state in the challenge so that if the AS 
> receives mismatched state and code_challange in step 3 the verification of 
> code verifier will fail. Effectively combining the cut and paste mitigation 
> with PKCE.
> 
> I haven’t had time to write this up, but if the code_challenge == SHA256 
> (SHA256(state) || token_endpoint URI || Authorization_endpoint URI || 
> client_id || code-veriyer) ,  then the attacker could not change state, 
> client_id, or token_endpoint  independently of code_challenge.  (note I am 
> using a hash of state to make storage size deterministic for the AS on the 
> grounds that the client already needs to be able to do the hash) (Some 
> attacks  change the client_id in the request so I am including it in the hash)
> 
> This is slightly more complicated than than S256, but not that much.  I wish 
> I had thought of this when we were doing PKCE.   Hit me with the stupid 
> stick, my fault.
> 
> I don’t know if it stops all the confused client attacks though.
> 
> If the client is confidential then it gives up it’s client secret assuming 
> compromised registration, so we can’t really count on that for symmetric 
> client authentication.
> 
> By including the token endpoint in the comparison if the client is sending 
> the code to the attacker the client will use a different token endpoint_uri 
> in to calculate the code_challenge than the GoodAS will use to verify it.    
> This would stop both cut and paste as well as stopping the attacker from 
> using the code if they get it.   The attacker can’t get Secret for state-0, 
> so it can’t create code_challenge that would be valid.
> 
> This stops the registration attack where the client gets a bad AS discovery 
> endpoint that has all the Good AS info including dynamic registration 
> endpoint but the bad AS token endpoint.   The bad AS would get the token, 
> client_secret and code_verier, but will fail pkce verification because the 
> token endpoint will be wrong.
> 
> The attack where the client registers with the good AS but with bad token 
> endpoint and Authorization endpoint gives the attacker the ability to change 
> the code_challenge that the Good AS is going to see.   It would need to make 
> a new challenge using state and the GoodAS token endpoint and it’s client_id.
> To do that it needs the code_verifier to use to calculate the hash to use as 
> the code_challenge value.  As long as the client is not tricked into 
> accepting a replay of the authentication response we should be safe.  The 
> client would need to do replay protection on the code_verifier values before 
> it makes a request to the token endpoint.
> 
> The BadAS could however make up a new code_challenge and code_verifier and 
> use that in the request. For this one the AS would need to do pull discovery 
> on the client to get a key, or the AS needs to return something in the 
> response.  This attack can completely proxy all the endpoints as far as the 
> client is concerned and is taking advantage of the AS saying you are granting 
> permission to site X based on the redirect URI.
> 
> I can’t see PKCE on it’s own being able to stop a client from being used as a 
> redirector back to the attacker unless you also returned the code_challenge 
> in the response from the authorization endpoint.
> 
> Hypothetically if we returned code_challenge in the response from the 
> authorization endpoint and have a new PKCE challenge method we might find it 
> covers all of the attacks.
> 
> We would need to put some serious analysis into this to see if it really 
> covers all the attacks.
> 
> It however doesn’t address the “token” response_type or steeling the access 
> token by impersonating the RS.
> 
> I think the correct way to stop the problem with access tokens is by audience 
> restricting them.
> To do that the client needs to provide an audience in it’s request and the AS 
> needs to include that in the AT.
> 
> I included the Authorization_endpoint URI in the hash to detect if the auth 
> request may have been tampered with to change the audience for the AT.
> 
> For implicit we could have a version of PKCE where the AS returns a parameter 
> with S256( client_id || authorization_endpoint URI || resource endpoint URI) 
> to verify the request was not tampered with, and that would allow the AT to 
> be properly audience restricted.
> 
> 
> This would be a completely new approach not involving discovery, logical 
> names for AS, or link relations.
> 
> Effectively this code_challenge method becomes a signature over parts of the 
> request and the implicit audience of the token_endpoint URI.
> 
> People keep asking why PKCE doesn’t stop these attacks, and it won’t with the 
> current PKCE methods,  however a new method along the lines I sketched out 
> may let it work, or I could be completely wrong.

Once you have written down something more definite I promise to implement it 
promptly such that we can do interop
testing early in the process.

Before John brought up this new PKCE mode I was on the Option A side of the 
fence now I’d like to see more
of this PKCE idea before committing to one or the other.

— Roland

”Everybody should be quiet near a little stream and listen."
From ’Open House for Butterflies’ by Ruth Krauss

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

_______________________________________________
OAuth mailing list
OAuth@ietf.org
https://www.ietf.org/mailman/listinfo/oauth

Reply via email to