On Sunday 10, 2016, OAuth Security Advisory: Authorization Server Mix-Up1 was issued. Nov Matake wrote an excellent article about it in Japanese2. To help understand the readers of the attack, I am translating the portion of his blog post explaining the attack with his permission, then expand on it.
The attacker can proxy the non-TLS-protected HTTP Request/Response between End-User and RP.
The RP connects with more than two OAuth Servers (IdPs) and one of them is under the control of the attacker. (e.g., the IdP was operated by the Attacker himself).
The RP is using the same redirect_uri for multiple IdPs and uses the ‘state’ value for determining which IdP is the response from.
Note: if the redirect_uri verification at the IdP is not the exact match with a pre-registered value, then this assumption may be relaxed.
In the following, the IdP under the control of the attacker is called AIdP (Attacker IdP) and the non-malicious IdP is called HIdP (Honest IdP).
Phase 1: The attacker gets the Victim’s code from HIdP.
The End-User clicks “Login with HIdP” button from any page of the RP.
The attacker proxies non-TLS-protected Browser->RP communication and sends “Login with AIdP” request to the RP. Then, it receives the redirect response at the Authorization Endpoint of the AIdP.
Attacker returns the redirect response to the Browser so that it will be taken to the Authorization Endpoint of HIdP. During the process, however, it uses the state value that is linked to the Authorization Request to AIdP that it received in the step 2. (Hereafter, since all the request is TLS-protected, the attacker’s proxy cannot intervene.)
The End-User clicks “Approve” at the HIdP.
HIdP returns the End-User to the RP’s redirect_uri with the state, code/token attached to either query or fragment.
The RP on receiving code/token, evaluates state value and determines that the Authorization Response is from AIdP.
RP sends the code and tokens to the AIdP’s Token Endpoint and other API Endpoints so that code and token of the HIdP are handed over to the attacker.
Phase 2: Attacker uses the victim’s code
Now that the attacker got hold of the victim’s code, code-V, now he uses it.
Now, the RP is behaving like it is providing services to the victim while in fact the user is the attacker. If the RP shows the data, the attacker can see it. If the access token allows the RP to modify the resource, then the attacker can modify the resource of the victim. In case of OpenID Connect, the Attacker has logged into RP as the victim.
How is it easy to launch this attack?
It depends. If the client is allowing to use only a set of trusted ASs, then the attack is unlikely because it does not redirect to AIdP to begin with.
If the client allows any ASs to be used, which in fact is not OAuth design 3, and the RP is not https only, then the attack becomes easier. Operating a FreeWiFi spot would be a good way to do it. In this case, the user is unlikely to notice the attack.
In case of OpenID Connect RP which supports dynamic client registration for random IdPs, it can become easier to exploit if the client uses code flow. If it uses the response type that returns ID Token in the front channel, it is immune to this attack.
There are several ways to address this issues.
Separate redirect_uri: Use different redirect_uri for each IdPs. For this to work, the HIdP must return error if redirect_uri of the client for the AIdP was received in the authorization request.
Issuer and client_id in response: Include the information that who has issued this authorization response and the client compares the issuer received with the one it got when registering, and compares received client_id with the client’s client_id for the issuer.
Tell the authoritative locations: Tell RP where the code / token can be used as a metadata.
AS white list: Use only the trusted ASs and do not allow arbitrary ASs.
HTTPS only RP: Use only HTTPS. No HTTP.
The separate redirect_uri strategy does not involve wire protocol change. However, it needs the HIdP to do the check of the client_id – redirect_uri pair check. However, it will involve re-registration of the clients and also the resulting re-authorization. Thus, while technically simple, it might not be attractive business-wise.
The issuer and client_id in response strategy is explained in draft-jones-mix-up-mitigation 4. The mitigation data that uses JWT is equivalent to ‘code id_token’, ‘code token id_token’, or ‘token’ response type in OpenID Connect. That’s why they are immune to this attack.
Tell the authoritative locations strategy is explained in draft-sakimura-oauth-meta 5, although it was not written to mitigate this attack. It was written to allow changing the token endpoint and resource endpoint depending on the user, but it still helps. If the AS returns issuer and supports discovery, then the received issuer string can be used to do the discovery and find the proper location to send the code.
AS white list strategy does not require AS cooperation. In most OAuth cases, this probably is the vast majority of the case right now. Even for OpenID Connect RPs, they tend to support only the well-known IdPs. That’s not what OpenID philosophy is trying to achieve, but it is the state of the world right now. That’s probably why we do not see this attack in the wild. I suppose OpenID Connect should deprecate response_type=code. The white list strategy seems to be the most viable option as it stands now.
HTTPS only RP strategy would also mitigate the attack as there will be no entry point for the attacker to insert himself. Think of it. If the RP is dealing with potential high value or sensitive data, do not you think it should be HTTPS only after all? If it is not, the adversary can insert himself as a man-in-the-middle (MITM) and will be able to steal the data irrespective of this attack being possible. If the site is only dealing with not-so-important data only, then it may wish to use HTTP and let the MITM, but in this case, there is no point to prevent mix-up attack either. Actually, if it is just dealing with not-important data, it may be easier to steal it with “Look at this cute kitten” RP.
My Recommendation against this attack
So, my recommendation is:
If the RP is dealing with potentially sensitive data, just make the site HTTPS only.
Use AS white list. Do not allow random ASs to be used.
Code phishing attack
There is a similar attack to this mix-up attack, which is explained in “Code phishing attack on OAuth 2.0 [RFC6749]”6. In this case, neither the separate redirect uri strategy nor issuer in response strategy works. The mitigation strategy 3 still works.
Having been working on Digital Identity since 2000.
Co-author of various identity related specifications like OpenID Connect, JSON Web Token.
Chair of the OpenID Foundation (2011-)
Vice Chair of the OpenID Foundation (2010),
Founder of OpenID Foundation Japan (2008-),
Trustee of Kantara Initiative (2009-).