J'avais d'abord mal interprété l'implémentation de l'horodatage de OAuth en pensant que cela signifiait qu'un horodatage qui n'était pas dans les 30 secondes après l'heure actuelle serait refusé, il s'est avéré que c'était faux pour plusieurs raisons y compris le fait que nous ne pouvions pas garantir que chaque horloge système était suffisamment synchronisée jusqu'aux minutes et aux secondes quel que soit le fuseau horaire. Ensuite, je l'ai relu pour plus de clarté:
"Sauf indication contraire du fournisseur de services, l'horodatage est exprimé en nombre de secondes depuis le 1er janvier 1970 00:00:00 GMT. La valeur d'horodatage DOIT être un entier positif et DOIT être égal ou supérieur à l'horodatage utilisé dans les demandes précédentes . "
source: http://oauth.net/core/1.0/#nonce
Cela signifie que les horodatages ne sont comparés que par rapport aux demandes précédentes de la même source, et non par rapport à l'horloge système de mon serveur.
Ensuite, j'ai lu une description plus détaillée ici: http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iii-security-architecture/
( TL; DR? - passez aux parties en gras ci-dessous)
Pour éviter que les requêtes compromises ne soient réutilisées (relues), OAuth utilise un nonce et un horodatage. Le terme nonce signifie "nombre utilisé une fois" et est une chaîne unique et généralement aléatoire destinée à être unique identifier chaque demande signée. En ayant un identifiant unique pour chaque demande, le fournisseur de services est en mesure d'empêcher les demandes d'être utilisées plus d'une fois. Cela signifie que le consommateur génère une chaîne unique pour chaque demande envoyée au fournisseur de services, et le fournisseur de services garde une trace de tous les nonces utilisés pour les empêcher d'être utilisés une deuxième fois. Étant donné que la valeur nonce est incluse dans la signature, elle ne peut pas être modifiée par un attaquant sans connaître le secret partagé.
L'utilisation de nonces peut être très coûteuse pour les fournisseurs de services car ils exigent un stockage persistant de toutes les valeurs de nonce reçues. Pour faciliter les implémentations, OAuth ajoute une valeur d'horodatage à chaque demande, ce qui permet au fournisseur de services de ne conserver que les valeurs nonce pendant une durée limitée. Lorsqu'une demande arrive avec un horodatage plus ancien que le délai retenu, il est rejeté car le fournisseur de services n'a plus de nonces de cette période. Il est prudent de supposer qu'une demande envoyée après la période autorisée la limite de temps est une attaque par rejeu. OAuth fournit un mécanisme général pour l'implémentation des horodatages mais laisse l'implémentation réelle à chaque fournisseur de services (un domaine que beaucoup croient devrait être revu par la spécification). Du point de vue, le vrai nonce est la combinaison de la valeur d'horodatage et de la chaîne de nonce. Ce n'est qu'ensemble qu'ils fournissent une valeur unique perpétuelle qui ne pourra plus jamais être utilisée par un attaquant.
La raison pour laquelle je suis confus est que si le Nonce n'est utilisé qu'une seule fois, pourquoi le fournisseur de services rejetterait-il jamais en fonction de l'horodatage? "Le fournisseur de services n'a plus de nonces de cette période" me déroute et sonne comme si un nonce peut être réutilisé tant qu'il se trouve dans les 30 secondes de la dernière fois qu'il a été utilisé.
Alors, quelqu'un peut-il clarifier cela pour moi? Quel est l'intérêt de l'horodatage si le nonce est à usage unique et que je ne compare pas l'horodatage à ma propre horloge système (car cela ne serait évidemment pas fiable). Il est logique que les horodatages ne soient relatifs que les uns aux autres, mais avec l'exigence unique de nonce, cela ne semble pas pertinent.
L'horodatage est utilisé pour permettre au serveur d'optimiser leur stockage des nonces. Fondamentalement, considérez le nonce de lecture comme la combinaison de l'horodatage et de la chaîne aléatoire. Mais en ayant un composant d'horodatage distinct, le serveur peut implémenter une restriction basée sur le temps en utilisant une courte fenêtre (disons, 15 minutes) et limiter la quantité de stockage dont il a besoin. Sans horodatage, le serveur aura besoin d'un stockage infini pour conserver chaque nonce jamais utilisé.
Supposons que vous décidiez d'autoriser jusqu'à 15 minutes de différence de temps entre votre horloge et celle du client et que vous gardiez une trace des valeurs nonce dans une table de base de données. La clé unique de la table sera une combinaison de "identifiant client", "jeton d'accès", "nonce" et "horodatage". Lorsqu'une nouvelle demande arrive, vérifiez que l'horodatage se trouve à moins de 15 minutes de votre horloge, puis recherchez cette combinaison dans votre table. S'il est trouvé, rejetez l'appel, sinon ajoutez-le à votre table et renvoyez la ressource demandée. Chaque fois que vous ajoutez un nouveau nonce à la table, supprimez tout enregistrement pour cette combinaison "identifiant client" et "jeton d'accès" avec un horodatage de plus de 15 minutes.
OK, après avoir suffisamment réfléchi, je crois que j'ai craqué celui-ci.
Ils veulent que je sache toujours l'horodatage de la dernière demande réussie qui a été faite afin que si un horodatage arrive avant cela, il sera ignoré.
De plus, le Nonce doit être unique, mais je ne vais les stocker que dans une certaine plage de dates.Par conséquent, si l'horodatage date de plusieurs heures, le Nonce sera supprimé et pourra ensuite être utilisé à nouveau, car le dernier horodatage utilisé étant également stockés, ils ne peuvent pas réutiliser une ancienne demande même si le Nonce est considéré comme unique car l'horodatage de cette demande serait obsolète.
Cependant, cela ne fonctionne qu'à cause de la signature. S'ils ont changé l'horodatage ou le Nonce sur une demande, la signature ne correspondra plus à la demande et sera refusée (car l'horodatage et le Nonce font tous deux partie de la création de la signature et n'ont pas la clé de signature).
Phew!
Si OAuth n'utilisait que l'horodatage, il serait relativement facile pour un attaquant de deviner quel serait l'horodatage suivant et d'injecter sa propre requête dans le processus. Il ne lui restait plus qu'à faire msgstr "horodatage précédent + 1".
En utilisant le nonce, qui est généré de manière cryptographiquement sécurisée (espérons-le), l'attaquant ne peut pas simplement injecter TS + 1, car il n'aura pas le nonce approprié pour s'authentifier.
Considérez-le comme une serrure de porte sécurisée qui nécessite à la fois une carte-clé et un code PIN. Vous pouvez voler la carte-clé, mais vous ne pouvez toujours pas passer la porte parce que vous ne connaissez pas le code PIN.