Comment OAuth 2 protège-t-il contre des choses comme les attaques par rejeu à l'aide du jeton de sécurité?


564

Si je comprends bien, la chaîne d'événements suivante se produit dans OAuth 2 afin Site-Ad'accéder aux informations de l' utilisateur à partir de Site-B.

  1. Site-As'inscrit Site-Bet obtient un Secret et une ID.
  2. Lorsque l' utilisateur dit Site-Ad'accéder Site-B, l' utilisateur est envoyé à l' Site-Bendroit où il indique Site-Bqu'il souhaite en effet accorder des Site-Aautorisations à des informations spécifiques.
  3. Site-Bredirige l' utilisateur vers Site-A, avec un code d'autorisation.
  4. Site-Atransmet ensuite ce code d'autorisation avec son secret Site-Ben échange d'un jeton de sécurité.
  5. Site-Aeffectue ensuite des demandes au Site-Bnom de l' utilisateur en regroupant le jeton de sécurité avec les demandes.

Comment tout cela fonctionne-t-il en termes de sécurité et de cryptage, à un niveau élevé? Comment OAuth 2 protège-t-il contre des choses comme les attaques par rejeu à l'aide du jeton de sécurité?


49
oauth2 a simplement expliqué ici: gist.github.com/mziwisky/10079157
Paolo

4
Lisez la spécification: tools.ietf.org/html/rfc6749 Vous pourriez être surpris de voir à quel point c'est compréhensible. C'est aussi correct ce qui n'est peut-être pas trop mal.
Kris Vandermotten du

1
Cette question et ses réponses (actuelles) se concentrent toutes sur un "type de subvention" particulier dans OAuth 2.0 (c.-à-d. code), Mais il existe d'autres types de subventions définis dans OAuth 2.0 qui sont pertinents pour différents cas d'utilisation (par exemple ceux qui ne sont pas liés à l'utilisateur).
Hans Z.28

4
Oh, pourquoi ne pas remplacer "Site B" par quelque chose de plus lisible comme "IdProvider Site"?
Yurii

Réponses:


1379

Fonctionnement d'OAuth 2.0 dans la vie réelle:

Je conduisais par la boulangerie d'Olaf sur le chemin du travail quand j'ai vu le beignet le plus délicieux dans la fenêtre - je veux dire, la chose ruisselait de bonté chocolatée. Je suis donc allé à l'intérieur et j'ai exigé "Je dois avoir ce beignet!". Il a dit "bien sûr que ce sera 30 $".

Ouais je sais, 30 $ pour un beignet! Ça doit être délicieux! J'ai atteint mon portefeuille quand soudain j'ai entendu le chef crier "NON! Pas de beignet pour toi". J'ai demandé: pourquoi? Il a dit qu'il n'acceptait que les virements bancaires.

Sérieusement? Oui, il était sérieux. J'ai failli m'éloigner juste là, mais ensuite le beignet m'a crié: "Mange-moi, je suis délicieux ...". Qui suis-je pour désobéir aux ordres d'un beignet? J'ai dit ok.

Il m'a remis une note avec son nom (le chef, pas le beignet): "Dis-leur qu'Olaf t'a envoyé". Son nom était déjà sur la note, donc je ne sais pas à quoi ça servait, mais ok.

J'ai conduit une heure et demie jusqu'à ma banque. J'ai remis la note au caissier; Je lui ai dit qu'Olaf m'a envoyé. Elle m'a donné un de ces regards, le genre qui dit: "Je peux lire".

Elle a pris ma note, a demandé mon identité, m'a demandé combien d'argent était acceptable pour lui donner. Je lui ai dit 30 $. Elle a griffonné et m'a remis une autre note. Celui-ci avait un tas de chiffres dessus, je suppose que c'est ainsi qu'ils gardent une trace des notes.

À ce stade, je meurs de faim. Je me suis précipité hors de là, une heure et demie plus tard j'étais de retour, debout devant Olaf avec ma note étendue. Il l'a pris, l'a regardé et a dit: "Je reviendrai".

Je pensais qu'il recevait mon beignet, mais après 30 minutes, j'ai commencé à me méfier. J'ai donc demandé au gars derrière le comptoir "Où est Olaf?". Il a dit "Il est allé chercher de l'argent". "Que voulez-vous dire?". "Il prend note à la banque".

Huh ... alors Olaf a pris note que la banque m'a donné et est retourné à la banque pour retirer de l'argent de mon compte. Puisqu'il avait le billet que la banque m'a donné, la banque savait que c'était le gars dont je parlais, et parce que j'ai parlé avec la banque, elle savait qu'elle ne devait lui donner que 30 $.

Cela a dû me prendre beaucoup de temps pour comprendre cela car au moment où je levai les yeux, Olaf se tenait devant moi, me tendant enfin mon beignet. Avant de partir, j'ai dû demander: "Olaf, as-tu toujours vendu des beignets de cette façon?". "Non, je le faisais différemment."

Huh. Alors que je retournais à ma voiture, mon téléphone a sonné. Je n'ai pas pris la peine de répondre, c'était probablement mon travail d'appeler pour me virer, mon patron est vraiment un ***. D'ailleurs, j'étais pris de réflexion sur le processus que je venais de traverser.

Je veux dire, pensez-y: j'ai pu laisser Olaf retirer 30 $ de mon compte bancaire sans avoir à lui donner les informations de mon compte. Et je n'avais pas à m'inquiéter qu'il retirerait trop d'argent parce que j'avais déjà dit à la banque qu'il n'était autorisé qu'à prendre 30 $. Et la banque savait qu'il était le bon gars parce qu'il avait le billet qu'ils m'avaient donné à donner à Olaf.

D'accord, je préfère lui donner 30 $ de ma poche. Mais maintenant qu'il avait cette note, je pouvais simplement dire à la banque de le laisser prendre 30 $ chaque semaine, alors je pouvais simplement me présenter à la boulangerie et je n'avais plus besoin d'aller à la banque. Je pourrais même commander le beignet par téléphone si je le voulais.

Bien sûr, je ne ferais jamais ça - ce beignet était dégoûtant.

Je me demande si cette approche a des applications plus larges. Il a mentionné que c'était sa deuxième approche, je pourrais l'appeler Olaf 2.0. Quoi qu'il en soit, je ferais mieux de rentrer chez moi, je dois commencer à chercher un nouvel emploi. Mais pas avant d'avoir obtenu un de ces shakes aux fraises de ce nouvel endroit à travers la ville, j'ai besoin de quelque chose pour laver le goût de ce beignet.


41
Eh bien, dans la pratique, Olaf devrait pouvoir retirer 30 $ de votre compte à tout moment, même si vous ne commandez aucun beignet. Fait intéressant, c'est le principal objectif des vrais scénarios oauth2.0 :) C'est certainement une excellente réponse, mais quiconque lit ceci, veuillez vous diriger vers le git gist que Paolo a mentionné dans son commentaire de la question ( gist.github.com/mziwisky/ 10079157 ). Une bonne lecture complémentaire pour rendre le concept clair.
Samiron

4
Excellente réponse mais 2 points à soulever: 1. Comme l'a souligné @Samiron, Olaf pourrait prendre 30 $ à tout moment. 2. Dans un vrai scénario OAuth2.0, Olaf ne pourra pas servir le beignet avant de retirer de l'argent de la banque. Dans cet exemple, il aurait pu garder le chèque et simplement remettre à Luis son beignet bien mérité. Donc, si nous modifions l'exemple pour faire en sorte que j'autorise Olaf à obtenir de la pâte d'un tiers que je connais, alors cela aurait plus de sens car Olaf devrait obtenir la pâte avant qu'il ne commence à cuire le beignet (en supposant le beignet solitaire Olaf avait était uniquement à des fins d'affichage!).
Ticker23

4
ticker23, l'histoire du beignet bat malheureusement votre correction technique - j'ai été vendu sur l'histoire quand je l'ai lu. Il a été écrit par Homer Simpson.
shevy

4
@Prageeth Olaf transporte toujours le billet de et vers la banque dans une boîte sécurisée qui fuit l'encre en cas de falsification, il faudrait plusieurs vies pour restaurer le billet. La banque prend également les empreintes digitales des clients lors de leur première visite, si Olaf perd ses doigts dans un accident de boulangerie, il devra alors demander à Luis de configurer à nouveau le virement bancaire, et la banque devra identifier Olaf par son tatouage Breaking Bread la prochaine fois .
Chris

11
J'adore les réponses mignonnes autant que la personne suivante, et quand leur gentillesse aide à rendre la réponse plus accessible, c'est génial ... mais à la fin de la journée, Stack Overflow vise à éduquer les gens, et cette histoire mignonne ne fait pas cela. Pour même comprendre l'analogie avec les beignets, vous devez déjà comprendre comment fonctionne OAuth2, mais le but de la réponse était censé expliquer précisément cela. Veuillez envisager de modifier cette (en haut) réponse pour expliquer réellement les concepts, pas seulement de les référencer obliquement à la fin ... même si cela se fait au prix d'une blague ou deux.
machineghost

133

D'après ce que j'ai lu, voici comment tout cela fonctionne:

Le flux général décrit dans la question est correct. À l'étape 2, l'utilisateur X est authentifié et autorise également l'accès du site A aux informations de l'utilisateur X sur le site B. À l'étape 4, le site retransmet son secret au site B, s'authentifiant ainsi que le code d'autorisation, indiquant ce qui il demande (jeton d'accès de l'utilisateur X).

Dans l'ensemble, OAuth 2 est en fait un modèle de sécurité très simple et le chiffrement n'entre jamais directement en jeu. Au lieu de cela, le secret et le jeton de sécurité sont essentiellement des mots de passe, et le tout n'est sécurisé que par la sécurité de la connexion https.

OAuth 2 n'a aucune protection contre les attaques de rejeu du jeton de sécurité ou du secret. Au lieu de cela, il repose entièrement sur le site B qui est responsable de ces éléments et ne les laisse pas sortir, et sur leur envoi via https pendant le transport (https protégera les paramètres d'URL).

Le but de l'étape du code d'autorisation est simplement la commodité, et le code d'autorisation n'est pas particulièrement sensible en soi. Il fournit un identifiant commun pour le jeton d'accès de l'utilisateur X pour le site A lors de la demande du site B pour le jeton d'accès de l'utilisateur X. Le simple identifiant de l'utilisateur X sur le site B n'aurait pas fonctionné, car il pourrait y avoir de nombreux jetons d'accès en attente en attente d'être distribués à différents sites en même temps.


28
Vous avez ignoré une fonction importante du code d'autorisation. Pourquoi ne pas simplement renvoyer le jeton d'actualisation (ce que vous appelez le jeton de sécurité) immédiatement, au lieu d'avoir l'étape supplémentaire de permuter le code d'autorisation pour cela? Parce que la capture du jeton d'actualisation permettrait des attaques de relecture, alors que le code d'autorisation ne peut être utilisé qu'une seule fois.
Maurice Naftalin

3
OK, @mauricen, cela a du sens .... Mais l'attaque de relecture ne pourrait-elle pas se produire aussi bien avec le jeton d'actualisation, car c'est ce qui finit par être transmis à chaque demande?
Mr Mikkél

15
Le code d'autorisation est transmis via l'utilisateur, il peut donc (par exemple) être stocké sous forme de cookie (voir stackoverflow.com/questions/4065657/… ). Le jeton d'actualisation passe directement entre les deux sites, il est donc beaucoup moins vulnérable.
Maurice Naftalin

Par curiosité, OAuth renvoie-t-il des identifiants uniques à utiliser par le programme? Par exemple, je me fie actuellement à l'adresse MAC pour l'identification de l'utilisateur, mais cela dit, les MAC ne sont pas fiables / facilement usurpés / etc. Je peux simplement supprimer le mécanisme d'identification d'adresse MAC et passer à OAuth s'il me permet d'identifier de manière unique les utilisateurs.
theGreenCabbage

1
Notez dans ce diagramme: tools.ietf.org/html/rfc6749#section-4.1 que le "Secret" n'est pas affiché, seulement l'identifiant client (ID dans la question). Pourquoi le secret est-il important et pourquoi n'est-il pas inclus dans le RFC? Dans la question, il y a également l'état local qui est recommandé d'être transmis lors de la transmission initiale de l'ID client (A), et la redirection vers le client avec le code d'autorisation pour se protéger contre XSSF.
David Williams

104

OAuth est un protocole avec lequel une application tierce peut accéder à vos données stockées sur un autre site Web sans votre compte et votre mot de passe. Pour une définition plus officielle, reportez-vous au wiki ou à la spécification.

Voici une démonstration de cas d'utilisation:

  1. Je me connecte à LinkedIn et souhaite connecter des amis qui figurent dans mes contacts Gmail. LinkedIn soutient cela. Il demandera une ressource sécurisée (ma liste de contacts gmail) à gmail. Je clique donc sur ce bouton:
    Ajouter une connexion

  2. Une page Web apparaît et affiche la page de connexion Gmail, lorsque j'entre mon compte et mon mot de passe:
    Ajouter une connexion

  3. Gmail affiche ensuite une page de consentement où je clique sur "Accepter": Ajouter une connexion

  4. LinkedIn peut désormais accéder à mes contacts dans Gmail: Ajouter une connexion

Voici un organigramme de l'exemple ci-dessus:

Ajouter une connexion

Étape 1: LinkedIn demande un jeton au serveur d'autorisation de Gmail.

Étape 2: Le serveur d'autorisation Gmail authentifie le propriétaire de la ressource et montre à l'utilisateur la page de consentement. (l'utilisateur doit se connecter à Gmail s'il n'est pas déjà connecté)

Étape 3: l'utilisateur accepte la demande de LinkedIn d'accéder aux données Gmail.

Étape 4: le serveur d'autorisation Gmail répond en retour avec un jeton d'accès.

Étape 5: LinkedIn appelle l'API Gmail avec ce jeton d'accès.

Étape 6: Le serveur de ressources Gmail renvoie vos contacts si le jeton d'accès est valide. (Le jeton sera vérifié par le serveur de ressources Gmail)

Vous pouvez obtenir plus d'informations sur OAuth ici .


Toutes vos images ont disparu. Avez-vous des chances de les charger dans stack.imgur?
ChrisF

1
Comment cela peut-il être correct? Ce processus n'est-il pas initié par l'utilisateur assis devant le navigateur, pas LinkedIn. Mais vous avez cela comme étape 3. C'est ce que je ne comprends pas.
Matt

17
L'explication la plus simple. Merci, je n'achèterai plus jamais de beignets
OverCoder

4ème étape linkedin revient avec un jeton d'autorisation. Cela doit être fourni dans la 5ème étape, où nous obtiendrons un jeton d'accès et un jeton d'actualisation qui pourraient être utilisés plus loin pour les ressources protégées.
amesh

@amesh Merci, vous avez raison, c'est le flux de code d'autorisation, ici je viens de dire de manière simplifiée pour montrer l'idée de base d'OAuth 2.
Owen Cao

24

Figure 1, relevée du RFC6750 :

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

13

Voici comment fonctionne Oauth 2.0, bien expliqué dans cet article

entrez la description de l'image ici


Pouvez-vous décrire OAUTH2 en termes de non-utilisation de Facebook ou d'un autre tiers, mais si vous utilisez une clé secrète et des jetons TOTP avec une application téléphonique pour sécuriser l'application Web?
Al Grant

Facebook est le serveur d'autorisation dans cet exemple qui émet un jeton d'accès à n'importe quel client afin qu'il puisse accéder aux API Facebook. Si vous souhaitez sécuriser vos API, vous devez implémenter votre propre serveur d'autorisation. Ensuite, vous décidez quel type de Grant vous souhaitez utiliser pour obtenir un jeton d'accès. dites-moi ce que vous voulez exactement? expliquera.
Suraj

Je regarde la mise en place avec la sécurité Springboot. Le client (téléphone) et la webapp échangent un secret lors de l'inscription - puis utilisez Google Authentifier pour générer un code basé sur l'heure / secret à saisir lors de la connexion en plus du mot de passe.
Al Grant

mon dernier commentaire vous éclaire-t-il plus? Voir mon profil pour info twitter
Al Grant

vous pouvez obtenir l'identifiant client et le secret lors de l'inscription. Ensuite, faites une demande de connexion par téléphone avec l'ID client à votre application Web (serveur d'autorisation). l'application Web valide l'ID du client et envoie l'OTP au téléphone. Le téléphone fait une autre demande avec le client secret à l'application Web pour échanger l'OTP avec un jeton d'accès. Le téléphone utilise ce jeton d'accès pour accéder aux ressources protégées sur la webapp. Je pense que ce serait le flux Oauth2 pour le scénario donné. faites-moi savoir si cela vous aide.
Suraj

10

Ceci est un joyau:

https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2

Très bref résumé:

OAuth définit quatre rôles:

  1. Propriétaire de la ressource
  2. Client
  3. Serveur de ressources
  4. Serveur d'autorisation

Vous (propriétaire de la ressource) avez un téléphone portable. Vous avez plusieurs comptes de messagerie différents, mais vous voulez que tous vos comptes de messagerie dans une seule application, vous n'avez donc pas besoin de continuer à changer. Ainsi, votre GMail (client) demande l'accès (via le serveur d'autorisation de Yahoo) à vos e-mails Yahoo (serveur de ressources) afin que vous puissiez lire les deux e-mails sur votre application GMail.

La raison pour laquelle OAuth existe est qu'il n'est pas sûr que GMail stocke votre nom d'utilisateur et votre mot de passe Yahoo.

entrez la description de l'image ici


8

L'autre réponse est très détaillée et répond à l'essentiel des questions posées par le PO.

Pour élaborer, et spécifiquement pour répondre à la question du PO "Comment OAuth 2 protège-t-il contre des choses comme les attaques par rejeu à l'aide du jeton de sécurité?", Il existe deux protections supplémentaires dans les recommandations officielles pour la mise en œuvre d' OAuth 2:

1) Les jetons auront généralement une courte période d'expiration ( http://tools.ietf.org/html/rfc6819#section-5.1.5.3 ):

Un court délai d'expiration pour les jetons est un moyen de protection contre les menaces suivantes:

  • rejouer...

2) Lorsque le jeton est utilisé par le site A, il est recommandé de le présenter non pas en tant que paramètres d'URL mais dans le champ d'en-tête de demande d'autorisation ( http://tools.ietf.org/html/rfc6750 ):

Les clients DEVRAIENT faire des demandes authentifiées avec un jeton porteur en utilisant le champ d'en-tête de demande "Autorisation" avec le schéma d'autorisation HTTP "Porteur". ...

La méthode "application / x-www-form-urlencoded" NE DEVRAIT PAS être utilisée sauf dans les contextes d'application où les navigateurs participants n'ont pas accès au champ d'en-tête de demande "Autorisation". ...

Le paramètre de requête URI ... est inclus pour documenter l'utilisation actuelle; son utilisation n'est pas recommandée, en raison de ses failles de sécurité


3

Voici peut-être l'explication la plus simple du fonctionnement d'OAuth2 pour les 4 types de subvention, c'est-à-dire 4 flux différents où l'application peut acquérir le jeton d'accès.

Similarité

Tous les flux de type de subvention ont 2 parties:

  • Obtenir un jeton d'accès
  • Utiliser un jeton d'accès

La 2ème partie 'utiliser le jeton d'accès' est la même pour tous les flux

Différence

La première partie du flux «obtenir un jeton d'accès» pour chaque type de subvention varie.

Cependant, en général, la partie «obtenir un jeton d'accès» peut être résumée en 5 étapes:

  1. Pré-enregistrez votre application (client) auprès du fournisseur OAuth, par exemple Twitter, etc. pour obtenir l'identifiant / secret du client
  2. Créez un bouton de connexion sociale avec l'ID client et les étendues / autorisations requises sur votre page afin que l'utilisateur cliqué soit redirigé vers le fournisseur OAuth pour être authentifié
  3. Le fournisseur OAuth demande à l'utilisateur d'accorder l'autorisation à votre application (client)
  4. Le fournisseur OAuth émet du code
  5. L'application (client) acquiert un jeton d'accès

Voici un diagramme côte à côte comparant en quoi chaque flux de type de subvention est différent en fonction des 5 étapes.

Ce diagramme provient de https://blog.oauth.io/introduction-oauth2-flow-diagrams/

entrez la description de l'image ici

Chacun a différents niveaux de difficulté de mise en œuvre, de sécurité et de cas d'utilisation. Selon vos besoins et votre situation, vous devrez en utiliser un. Lequel utiliser?

Informations d'identification du client : si votre application ne sert qu'un seul utilisateur

Informations d'identification du mot de passe du propriétaire de la ressource : cela ne doit être utilisé qu'en dernier recours, car l'utilisateur doit remettre ses informations d'identification à l'application, ce qui signifie que l'application peut faire tout ce que l'utilisateur peut faire.

Code d'autorisation : la meilleure façon d'obtenir l'autorisation de l'utilisateur

Implicite : si votre application est une application mobile ou une seule page

Il y a plus d'explications sur le choix ici: https://blog.oauth.io/choose-oauth2-flow-grant-types-for-app/

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.