Prévenir les attaques et rediriger les utilisateurs avec les paramètres d’état OAuth 2.0

Les protocoles d’autorisation fournissent un paramètre state qui vous permet de rétablir l’état précédent de votre application. Le paramètre state préserve certains objets d’état définis par le client dans la demande d’autorisation et les met à la disposition du client dans la réponse.

Attaques CSRF

La principale raison d’utiliser le paramètre state est d’atténuer les attaques CSRF en utilisant une valeur unique et non devinable associée à chaque demande d’authentification sur le point d’être initiée. Cette valeur vous permet d’empêcher l’attaque en confirmant que la valeur provenant de la réponse correspond à celle que vous avez envoyée.

Le paramètre state est une chaîne de caractères, vous pouvez donc y encoder toute autre information. Vous envoyez une valeur aléatoire lors du lancement d’une demande d’authentification et vous validez la valeur reçue lors du traitement de la réponse. Vous stockez quelque chose du côté de l’application client (dans les témoins, la session ou le stockage local) qui vous permet d’effectuer la validation. Si vous recevez une réponse dont l’état ne correspond pas, vous pouvez en déduire que vous êtes peut-être la cible d’une attaque, car la réponse provient soit d’une demande non sollicitée, soit d’une personne qui tente de falsifier la réponse.

Une attaque CSRF cible spécifiquement les demandes de changement d’état pour initier une action au lieu d’obtenir des données utilisateur, car l’attaquant n’a aucun moyen de voir la réponse à la demande falsifiée. Dans la plupart des cas, le paramètre d’état doit être un nombre aléatoire, utilisé pour établir une corrélation entre la demande et la réponse reçue à la suite de l’authentification.

La plupart des trousses SDK OIDC et OAuth modernes, y compris Auth0.js dans les applications monopages, gèrent automatiquement la génération et la validation de l’état.

Définir et comparer les valeurs des paramètres d’état

  1. Avant de rediriger une demande vers le fournisseur d’identité (IdP), demandez à l’application de générer une chaîne aléatoire. Par exemple :

    xyzABC123

    Was this helpful?

    /
    la longueur autorisée pour l’état n’est pas illimitée. Si vous obtenez l’erreur 414 Request-URI Too Large, essayez une valeur plus petite.

  2. Enregistrez la chaîne localement. Par exemple :

    storeStateLocally(xyzABC123)

    Was this helpful?

    /

  3. Ajoutez le paramètre state à la demande (encodage d’URL si nécessaire). Par exemple :

    // Encode the String   
    tenant.auth0.com/authorize?...&state=xyzABC123

    Was this helpful?

    /
    Une fois la demande envoyée, Auth0 redirige l’utilisateur vers l’application. La valeur state sera incluse dans cette redirection. Notez qu’en fonction du type de connexion utilisée, cette valeur peut se trouver dans le corps de la requête ou dans la chaîne de requête.
    /callback?...&state=xyzABC123

    Was this helpful?

    /

  4. Récupérez la valeur state renvoyée et comparez-la à celle que vous avez enregistrée précédemment. Si les valeurs correspondent, approuvez la réponse d’authentification, sinon refusez-la.

    // Decode the String
    var decodedString = Base64.decode(encodedString);
    if(receivedState === retrieveStateStoredLocally()) {
     // Authorized request
    } 
    else {
      // This response is not for us, reject it
    }

    Was this helpful?

    /

Rediriger les utilisateurs

Vous pouvez utiliser le paramètre state pour coder un état de l’application qui placera l’utilisateur à son emplacement d’avant le début du processus d’authentification. Par exemple, si un utilisateur a l’intention d’accéder à une page protégée dans votre application et que cette action déclenche une demande d’authentification, vous pouvez stocker cette URL pour rediriger l’utilisateur vers la page voulue une fois l’authentification terminée.

Générez et stockez un nombre aléatoire localement (dans les témoins, la session ou le stockage local) avec toutes les données d’état souhaitées, comme l’URL de redirection. Utilisez le nombre aléatoire comme état dans le message de protocole. Si l’état renvoyé correspond à le nombre aléatoire stockée, acceptez le message OAuth2 et récupérez les données d’état correspondantes dans le stockage. C’est l’approche utilisée dans auth0.js.

Utiliser l’URL stockée pour rediriger les utilisateurs

  1. Définissez la valeur du paramètre d’état nombre aléatoire que vous avez utilisé pour atténuer les attaques CSRF comme expliqué ci-dessus.

  2. Stockez le nombre aléatoire localement, en l’utilisant comme clé pour stocker toutes les autres informations relatives à l’état de l’application, comme l’URL où l’utilisateur a l’intention de se rendre. Par exemple :

    {
      "xyzABC123" : {
        redirectUrl: '/protectedResource',
        expiresOn: [...]
      }
    }

    Was this helpful?

    /

  3. Authentifiez l’utilisateur, en envoyant le nombre aléatoire généré comme état.

  4. Dans le cadre du traitement du rappel et de la validation de la réponse, vérifiez que l’état renvoyé correspond au nombre aléatoire stocké localement. Si c’est le cas, récupérez le reste de l’état de l’application (comme le redirectUrl).

  5. Une fois le traitement du rappel terminé, redirigez l’utilisateur vers l’URL précédemment enregistrée.

Autre procédé de redirection

  1. Générez et stockez localement une valeur de nombre aléatoire.

  2. Encodez tout état souhaité (comme l’URL de redirection) avec le nombre aléatoire dans un message protégé (qui devra être crypté/signé pour éviter toute falsification).

  3. Dans le traitement de la réponse, déprotégez le message, en récupérant le nombre aléatoire et les autres propriétés stockés.

  4. Validez la correspondance entre le nombre aléatoire inclus et celui stocké localement et, le cas échéant, acceptez le message OAuth2.

Limites et considérations

  • Choisissez une méthode de stockage en fonction de votre type d’application.

    Type d’App Recommandation de Stockage
    Application Web standard Témoin ou session
    SPA Navigateur local
    Application native Mémoire ou local

  • Du point de vue de la sécurité, ni la demande ni la réponse ne sont protégées en termes d’intégrité, ce qui permet à n’importe quel utilisateur de les manipuler. Il en va de même pour l’ajout d’un paramètre à redirect_uri.

  • La longueur autorisée pour la valeur du paramètre d’état n’est pas illimitée. Si vous obtenez l’erreur 414 Request-URI Too Large, essayez une valeur plus petite.

  • Transmettre des URL en texte clair ou de manière prévisible n’est pas sécurisé. Assurez-vous que la valeur du paramètre d’état est :

    • Unique et opaque afin qu’elle puisse être utilisée pour la défense contre les attaques CSRF et par hameçonnage.

    • Si elle est stockée dans un témoin, elle doit être signée afin d’éviter toute falsification.

En savoir plus