# OAuth 2 Substitution Attack

## **Description de l’Attaque**

Cette attaque suppose que l’attaquant et la victime sont des **Resource Owners** inscrits auprès du même **Authorization Server**.

1. L’attaquant initie un **Authorization Code Flow** *(ou **Implicit Flow**)*.
2. L’attaquant interrompt le scénario à[ l’étape 3 ](https://guide-api-rest.marmicode.fr/securite-des-apis-rest/oauth-2/oauth-2-authorization-code-flow)*(quand il obtient l'**Authorization Code** ou l'**Access Token**)*.
3. L’attaquant incite la victime à suivre un lien pointant vers l’URL contenant l'Authorization code ou l'**Access Token** obtenu à l’étape précédente *(social engineering ou application malicieuse)*.
4. La victime suit l’URL vers le **Client** qui interagit alors avec les ressources de l’attaquant.

## **Quelques Exemples de Scénarios**

### Banque

1. L’attaquant et la victime sont clients d’une même banque.
2. La victime se retrouve alors sur l’application de la banque avec les données de l’attaquant.
3. En pensant télécharger son propre RIB, la victime récupère le RIB de l’attaquant.

### Messagerie

1. L’attaquant usurpe l’identité de la victime en créant un faux compte sur Facebook.
2. L’attaquant ajoute des "amis" de la victime.
3. L’attaquant s’inscrit sur une application de messagerie utilisant le service OAuth 2 de Facebook.
4. La victime se retrouve sur l’application de messagerie avec le compte de l’attaquant et échange avec ses propres amis via ce compte.
5. L’attaquant se connecte à son tour sur l’application de messagerie pour récupérer les correspondances de la victime.

## **Origine de la Vulnérabilité et Solution**

Cette vulnérabilité existe car OAuth 2 n’impose aucun lien entre l’étape 1 *(**demande** de l'**Authorization Code** ou **Access Token**)* et l’étape 3 *(**récupération** de l'**Authorization Code** ou **Access Token**)*.

Heureusement, il existe un paramètre **optionnel** `state`, initialement prévu pour que le **Client** puisse retrouver son état initial après l’autorisation.

Ce paramètre est désormais détourné de son objectif initial. Il permet de lutter contre cette attaque en vérifiant que le **Resource Owner** autorisé est bien celui à l’origine de la demande.

Cela s’implémente le plus souvent de la façon suivante :

1. Le **Client** génère un **nonce** imprédictible et unique à chaque demande d’autorisation.
2. Le **Client** le positionne par exemple dans un "cookie" et dans le paramètre `state` avant de rediriger le **Resource Owner** vers l'**Authorization Server**.
3. L'**Authorization Server** redirige alors le **Resource Owner** vers le **Client** en transmettant le `state` à l’identique.
4. Le **Client** vérifie que le `state` correspond au **nonce** dans le cookie.

Malheureusement, il s’agit d’une vulnérabilité conceptuelle dans le standard OAuth 2 et qui se joue à un mot près.

Le paramètre `state` est donc “RECOMMENDED” au lieu d’être “REQUIRED” laissant ainsi le choix au **Client** de rester vulnérable à cette attaque.

Si l'**Authorization Server** rend ce paramètre obligatoire, il n’est alors plus conforme au standard.

**OpenID Connect** ajoute une notion de **nonce** plus explicite mais pour rester compatible avec OAuth 2, ce paramètre est également optionnel 😭.

## **Solution et Contournements**

La solution la plus rigoureuse est de rendre le paramètre `state` obligatoire mais bien sûr, sans vérification côté **Client**, ce paramètre est inutile. Par contre, on sort alors du standard.

L'**Authorization Server** peut réduire le périmètre d’autorisation en l’absence du paramètre `state`.

C’est l’une des raisons pour lesquelles il est nécessaire de réduire la durée de vie de l'**Authorization Code** au minimum. En revanche, si le client utilise l'**Implicit Flow**, on ne peut pas réduire la durée de vie de l'**Access Token** à quelques minutes.
