web-dev-qa-db-fra.com

Laravel 5.6 - Authentification SPA par cookie Passport JWT pour les API auto-consommables?

NOTE: J'avais 4 primes pour cette question, mais aucune des réponses votées ci-dessous n'est la réponse nécessaire pour cette question. Tout ce dont vous avez besoin est dans la mise à jour 3 ci-dessous, il suffit de rechercher le code Laravel à implémenter.


MISE À JOUR 3: Cet organigramme est exactement le flux que j'essaie d'accomplir, tout ce qui suit est la question initiale avec certaines mises à jour plus anciennes. Cet organigramme résume tout ce qui est nécessaire.

Les parties vertes dans l’organigramme ci-dessous sont les parties que je sais faire. Les parties rouges accompagnées de leurs notes sont ce que je recherche pour obtenir de l’aide en utilisant le code Laravel.

enter image description here


J'ai fait beaucoup de recherches, mais les informations étaient toujours courtes et incomplètes en ce qui concerne l'utilisation de Laravel avec un cookie JWT httponly pour une API auto-consommatrice (la plupart des tutoriels en ligne ne montrent que JWT). Il semble qu’un cookie contenant un JWT de Passport devrait être utilisé pour identifier l’utilisateur du côté Javascript lorsqu’il est envoyé avec chaque demande adressée au serveur afin de valider que l’utilisateur est bien ce qu’ils disent. sont.

Il y a aussi quelques éléments supplémentaires nécessaires pour avoir une idée complète de la façon de faire fonctionner cette configuration, que je n'ai pas rencontrés dans un seul tutoriel qui couvre ceci:

  1. Laravel Passport (not tymon auth) pour générer JWT crypté et l’envoyer comme cookie httponly en réponse après la connexion à partir de JS. Quel middleware utiliser? Si les jetons d'actualisation renforcent la sécurité, comment les implémenter?
  2. JavaScript (axios par exemple) api pseudo-code qui appelle le point de terminaison auth, comment un cookie est transmis à backendly et comment le jeton de vérification de backend est-il valide.
  3. Si un seul compte est connecté à partir de plusieurs appareils, puis un appareil est volé, comment révoquer l'accès de tous les appareils utilisateur autorisés (en supposant que l'utilisateur modifie le mot de passe d'un appareil connecté dont il a le contrôle)?
  4. À quoi ressembleraient généralement les méthodes du contrôleur de connexion/enregistrement, déconnexion, changement de mot de passe, mot de passe oublié pour gérer la création/validation/révocation de jetons?
  5. Intégration de jeton CSRF.

J'espère qu'une réponse à cette question constituera un guide facile à suivre pour les futurs lecteurs et ceux qui luttent actuellement pour trouver une réponse couvrant les points ci-dessus sur une API auto-consommatrice.

PDATE 1:

  1. Veuillez noter que j'ai déjà essayé le CreateFreshApiToken, mais cela n'a pas fonctionné pour révoquer les jetons de l'utilisateur (pour les points 3 et 4 ci-dessus). Ceci est basé sur ce commentaire par un noyau laravel, en parlant du middleware CreateFreshApiToken:

Les jetons JWT créés par ce middleware ne sont stockés nulle part. Ils ne peuvent pas être révoqués ou "ne pas exister". Ils fournissent simplement un moyen d'autoriser vos appels d'api par le cookie laravel_token. Ce n'est pas lié aux jetons d'accès. En outre, vous n'utiliseriez normalement pas de jetons émis par les clients sur la même application qui les émet. Vous les utiliseriez dans une application tierce ou tierce. Utilisez le middleware ou les jetons émis par le client, mais pas les deux en même temps.

Donc, il semble être en mesure de prendre en compte les points 3 et 4 pour révoquer les jetons. Ce n'est pas possible si vous utilisez le middleware CreateFreshApiToken.

  1. Du côté des clients, il semble que Authorization: Bearer <token> n’est pas la voie à suivre s’agissant du cookie sécurisé httpOnly. Je pense que la requête/réponse est supposée inclure le cookie sécurisé httpOnly comme en-tête de requête/réponse, comme ceci, basé sur le laravel docs:

Lorsque vous utilisez cette méthode d’authentification, l’échafaudage JavaScript Laravel par défaut) indique à Axios de toujours envoyer les en-têtes X-CSRF-TOKEN et X-Requested-With.

headerswindow.axios.defaults.headers.common = {
    'X-Requested-With': 'XMLHttpRequest',
    'X-CSRF-TOKEN': (csrf_token goes here)
};

C'est aussi la raison pour laquelle je cherche une solution qui couvre tous les points ci-dessus. Toutes mes excuses, j'utilise Laravel 5.6 pas 5.5.

PDATE 2:

Il semble que la combinaison Accord de mot de passe/Actualiser l’attribution de jetons est la voie à suivre. Vous recherchez un guide d'implémentation facile à suivre à l'aide de la combinaison Accord de mot de passe/Actualiser l'attribution de jeton.

Mot de passe Subvention: Cette subvention convient aux clients en qui nous avons confiance, comme une application mobile pour notre propre site Web. Dans ce cas, le client envoie les informations d'identification de connexion de l'utilisateur au serveur d'autorisation, lequel émet directement le jeton d'accès.

Refresh Token Grant: Lorsque le serveur émet un jeton d'accès, il définit également une date d'expiration pour le jeton d'accès. L'attribution de jeton d'actualisation est utilisée lorsque nous souhaitons actualiser le jeton d'accès après son expiration. Dans ce cas, le serveur d'autorisation envoie un jeton d'actualisation lors de l'émission du jeton d'accès, qui peut être utilisé pour demander un nouveau jeton d'accès.

Je cherche une réponse facile à mettre en œuvre, simple et globale à l’aide du combo Accorder le mot de passe/actualiser les jetons qui couvre toutes les parties des 5 points originaux ci-dessus avec le cookie httpOnly secure, créant/révoquant/jetons d'actualisation, création de cookies de connexion, révocation de cookies de déconnexion, méthodes de contrôleur, CSRF, etc.

49
Wonka

Laravel Passport JWT

  1. Pour utiliser cette fonctionnalité, vous devez désactiver la sérialisation des cookies. Laravel 5.5 présente un problème de sérialisation/non sérialisation des valeurs de cookies. Vous pouvez en savoir plus à ce sujet ici ( https://laravel.com/docs/5.5/upgrade )

  2. Sois sûr que

    • vous avez <meta name="csrf-token" content="{{ csrf_token() }}"> dans la tête du modèle de votre lame

    • axios est configuré pour utiliser csrf_token à chaque requête.

Vous devriez avoir quelque chose comme ça dans resources/assets/js/bootstrap.js

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
  window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
  console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
  1. Configurez les itinéraires d'authentification expliqués ici ( https://laravel.com/docs/5.5/authentication )
  2. Le passeport de configuration est expliqué ici ( https://laravel.com/docs/5.5/passport ).

Les parties importantes sont:

  • ajoutez le trait Laravel\Passport\HasApiTokens à votre modèle User
  • définissez l'option driver de la garde api d'authentification sur passport dans votre config/auth.php
  • ajoutez le middleware \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class, à votre groupe de middleware web dans app/Http/Kernel.php

Notez que vous pouvez probablement ignorer les migrations et la création de clients.

  1. Faites une demande POST à /login En transmettant vos informations d'identification. Vous pouvez faire une demande AJAX ou un formulaire normal à envoyer.

Si la demande de connexion est AJAX (en utilisant axios), les données de réponse seront au format HTML, mais ce qui vous intéresse est le code de statut.

axios.get(
  '/login, 
  {
    email: '[email protected]',
    password: 'secret',
  },
  {
    headers: {
      'Accept': 'application/json', // set this header to get json validation errors.
    },
  },
).then(response => {
  if (response.status === 200) {
      // the cookie was set in browser
      // the response.data will be HTML string but I don't think you are interested in that
    }
    // do something in this case
}).catch(error => {
  if (error.response.status === 422) {
    // error.response.data is an object containing validation errors
  }
  // do something in this case
});

Lors de la connexion, le serveur trouve l'utilisateur à l'aide des informations d'identification fournies, génère un jeton basé sur les informations de l'utilisateur (identifiant, email ...) (ce jeton n'est enregistré nulle part), puis le serveur renvoie une réponse avec un cookie crypté contenant le jeton généré. .

  1. Effectuez un appel API vers un itinéraire protégé.

En supposant que vous avez un itinéraire protégé

Route::get('protected', 'SomeController@protected')->middleware('auth:api');

Vous pouvez faire un appel ajax en utilisant axios comme d’habitude. Les cookies sont automatiquement configurés.

axios.get('/api/protected')
  .then(response => {
    // do something with the response
  }).catch(error => {
    // do something with this case of error
  });

Lorsque le serveur reçoit l'appel, il déchiffre la demande laravel_cookie Et obtient les informations de l'utilisateur (ex: id, email ...). Ensuite, avec cette information, une recherche dans la base de données permet de vérifier si l'utilisateur existe. Si l'utilisateur est trouvé, il est autorisé à accéder à la ressource demandée. Sinon un 401 est retourné.

Invalidation du jeton JWT. Comme vous mentionnez le commentaire, vous n'avez pas à vous inquiéter car ce jeton n'est enregistré nulle part sur le serveur.

Mise à jour

Concernant le point 3 Laravel 5.6 Auth a une nouvelle méthode logoutOtherDevices. Vous pouvez en apprendre plus à partir de cet emplacement ( https://laracasts.com/series/whats-new -in-laravel-5-6/episodes/7 ) car la documentation est très légère.

Si vous ne parvenez pas à mettre à jour votre version de Laravel), vous pouvez vérifier comment elle est effectuée dans la version 5.6 et construire votre propre implémentation pour la version 5.5.

Point 4 de votre question. Jetez un coup d'œil aux contrôleurs trouvés dans app/Http/Controllers/Auth.

En ce qui concerne access_tokens et refresh_tokens, il s'agit d'une approche totalement différente et plus complexe. Vous pouvez trouver de nombreux tutoriels en ligne expliquant comment le faire.

J'espère que ça aide.

PS Bonne année!! :)

10
Mirceac21

J'ai également implémenté Laravel passeport dans mon projet et je pense avoir couvert la plupart des points que vous avez mentionnés dans votre question.

  1. J'ai utilisé l'attribution de mot de passe pour générer un jeton d'accès et un jeton d'actualisation. Vous pouvez suivre ces étapes pour configurer le passeport et mettre en œuvre la concession de passeport. Dans votre méthode de connexion, vous devez valider les informations d'identification de l'utilisateur, générer les jetons et associer le cookie ( Attacher le cookie à la réponse ) à la réponse. Si vous avez besoin, je peux vous donner quelques exemples.
  2. J'ai ajouté deux middleware pour CORS (Gestion des en-têtes de demandes entrantes) et pour vérifier si le jeton d'accès entrant est valide ou non, sinon valide, générer le jeton d'accès à partir du jeton d'actualisation stocké ( Jeton d'actualisation ). Je peux vous montrer l'exemple.
  3. Après la connexion, toutes les demandes du côté client doivent contenir l’en-tête Authorization (Authorization: Bearer <token>).

Faites-moi savoir si vous êtes clair avec les points ci-dessus.

6
Wellwisher
  • Laravel Passport est une implémentation de The PHP Ligue OAuth Server
  • Le type d'octroi de mot de passe peut être utilisé pour l'authentification par nom d'utilisateur + mot de passe
  • N'oubliez pas de masquer les informations d'identification de votre client en effectuant la demande d'authentification dans un proxy.
  • Enregistrez le jeton d'actualisation dans un cookie HttpOnly pour minimiser le risque d'attaques XSS

Plus d'informations que vous pouvez voir ici

http://esbenp.github.io/2017/03/19/modern-rest-api-laravel-part-4/

6
Ismoil Shifoev

J'essaierai d'y répondre de manière générique afin que la réponse soit applicable à travers les frameworks, les implémentations et les langages car les réponses à toutes les questions peuvent être dérivées des spécifications générales du protocole ou de l'algorithme.

Quel type de subvention OAuth 2.0 dois-je utiliser?)

C'est la première chose à décider. En ce qui concerne SPA, les deux options possibles sont:

  1. Octroi de code d'autorisation (recommandé, à condition que le secret du client soit stocké côté serveur)
  2. Octroi des informations d'identification du mot de passe du propriétaire de la ressource

Les raisons pour lesquelles je ne mentionne pas le type de subvention implicite en option sont les suivantes:

  1. L'étape d'authentification du client en fournissant le secret client et le code d'autorisation est manquante. Donc moins de sécurité
  2. Le jeton d'accès est renvoyé sous forme de fragment d'URL (afin que le jeton ne soit pas envoyé au serveur), qui restera dans l'historique du navigateur.
  3. En cas d'attaque XSS, le script malveillant peut très bien envoyer le jeton à un serveur distant sous le contrôle d'un attaquant

(Le type d'octroi d'informations d'identification du client est exclu de la présente discussion, car il est utilisé lorsque le client n'agit pas au nom d'un utilisateur. Par exemple, un travail par lots)

En cas de type d'autorisation Code d'autorisation, le serveur d'autorisation est généralement un serveur différent du serveur de ressources. Il est préférable de séparer le serveur d'autorisation et de l'utiliser comme serveur d'autorisation commun pour tous les SPA de l'entreprise. C'est toujours la solution recommandée.

Ici (dans le type d’octroi de code d’autorisation), le flux ressemble à celui ci-dessous:

  1. l'utilisateur clique sur le bouton de connexion de la page de destination du SPA
  2. l'utilisateur est redirigé vers la page de connexion du serveur d'autorisation. L'identifiant du client est fourni dans le paramètre de requête d'URL
  3. L'utilisateur entre ses informations d'identification et clique sur le bouton de connexion. Le nom d'utilisateur et le mot de passe seront envoyés au serveur d'autorisation à l'aide de HTTP POST. Les informations d'identification doivent être envoyées dans le corps de la demande ou dans l'en-tête et NON dans l'URL (car les URL sont consignées dans l'historique du navigateur et sur le serveur d'applications). De plus, les en-têtes HTTP de mise en cache appropriés doivent être définis, de sorte que les informations d'identification ne soient pas mises en cache: Cache-Control: no-cache, no-store, Pragma: no-cache, Expires: 0
  4. Le serveur d'autorisation authentifie l'utilisateur par rapport à une base de données utilisateur (serveur LDAP, par exemple) où le nom d'utilisateur et le hachage du mot de passe de l'utilisateur (algorithmes de hachage tels que Argon2, PBKDF2, Bcrypt ou Scrypt) sont stockés avec un sel aléatoire.
  5. En cas d'authentification réussie, le serveur d'autorisation extrairait de sa base de données l'URL de redirection par rapport à l'ID client fourni dans le paramètre de requête d'URL. L'URL de redirection est l'URL du serveur de ressources.
  6. L'utilisateur sera ensuite redirigé vers un noeud final de serveur de ressources avec un code d'autorisation dans le paramètre de requête d'URL.
  7. Le serveur de ressources fera alors une requête HTTP POST au serveur d'autorisation pour le jeton d'accès. Le code d'autorisation, l'id du client, le secret du client doivent figurer dans le corps de la requête. être utilisé)
  8. Le serveur d'autorisation renverrait le jeton d'accès et le jeton d'actualisation dans le corps ou l'en-tête de la réponse (avec l'en-tête de mise en cache approprié mentionné ci-dessus).
  9. Le serveur de ressources va maintenant rediriger l'utilisateur (code de réponse HTTP 302) vers l'URL du SPA en définissant des cookies appropriés (à expliquer en détail ci-dessous).

Par ailleurs, pour le type d’octroi d’autorisation, avec le mot de passe du propriétaire de la ressource, le serveur d’autorisation et le serveur de ressources sont identiques. Il est plus facile à mettre en œuvre et peut également être utilisé si cela convient aux exigences et aux délais de mise en œuvre.

Reportez-vous également à ma réponse à ce sujet ici pour plus de détails sur le type de subvention du propriétaire de la ressource.

Il peut être important de noter ici que dans un SPA, toutes les routes protégées ne doivent être activées qu'après avoir appelé un service approprié pour garantir la présence de jetons valides dans la demande. De même, les API protégées doivent également disposer de filtres appropriés pour valider les jetons d'accès.

Pourquoi ne devrais-je pas stocker les jetons dans le stockage local ou le stockage de session du navigateur?

De nombreux SPA stockent l'accès et/ou actualisent le jeton dans le stockage local ou le stockage de session du navigateur. La raison pour laquelle je pense que nous ne devrions pas stocker les jetons dans ces stockages de navigateur est la suivante:

  1. Si XSS se produit, le script malveillant peut facilement lire les jetons à partir de là et les envoyer à un serveur distant. Le serveur distant ou l'attaquant n'aura aucun problème à emprunter l'identité de l'utilisateur victime.

  2. le stockage local et le stockage de session ne sont pas partagés entre les sous-domaines. Ainsi, si deux SPA fonctionnent sur des sous-domaines différents, nous n'obtiendrons pas la fonctionnalité SSO car le jeton stocké par une application ne sera pas disponible pour l'autre application de l'organisation.

Si, toutefois, les jetons sont toujours stockés dans l'un de ces stockages de navigateur, une empreinte digitale appropriée doit être incluse. L'empreinte digitale est une chaîne d'octets aléatoire très forte sur le plan cryptographique. La chaîne Base64 de la chaîne brute sera alors stockée dans un cookie HttpOnly, Secure, SameSite avec le préfixe de nom __Secure-. Valeurs propres pour les attributs Domain et Path. Un hachage SHA256 de la chaîne sera également passé dans une revendication de JWT. Ainsi, même si une attaque XSS envoie le jeton d'accès JWT à un serveur distant contrôlé par un attaquant, il ne peut pas envoyer la chaîne d'origine dans le cookie et le serveur peut donc rejeter la demande en raison de l'absence du cookie. En outre, l'injection de script et XSS peut être davantage atténuée en utilisant un content-security-policy en-tête de réponse.

Remarque:

  1. SameSite=strict s'assure que le cookie donné n'accompagnera pas les demandes provenant d'un autre site (AJAX ou via l'hyperlien suivant). En termes simples, toute requête provenant d’un site ayant le même "domaine enregistrable" que le site cible sera autorisée. Par exemple. Si " http://www.example.com " est le nom du site, le domaine enregistrable est "example.com". Pour plus de détails, voir référence no. 3 dans la dernière section ci-dessous. Ainsi, il offre une certaine protection contre le CSRF. Toutefois, cela signifie également que si l'URL fournie est un forum, un utilisateur authentifié ne peut pas suivre le lien. S'il s'agit d'une restriction sérieuse pour une application, SameSite=lax _ peut être utilisé, ce qui autorisera les requêtes intersites tant que les méthodes HTTP sont sécurisées, à savoir. GET, HEAD, OPTIONS et TRACE. Comme CSRF est basé sur des méthodes peu sûres comme POST, PUT, DELETE, lax fournit toujours une protection contre CSRF

  2. Pour permettre à un cookie d'être transmis dans toutes les demandes à n'importe quel sous-domaine de "exemple.com", l'attribut de domaine du cookie doit être défini sur "exemple.com".

Pourquoi devrais-je stocker un jeton d'accès et/ou un jeton d'actualisation dans des cookies?

  1. Lors du stockage des jetons dans les cookies, nous pouvons définir le cookie comme secure et httpOnly. Ainsi, si XSS se produit, le script malveillant ne peut pas lire et les envoyer au serveur distant. XSS peut toujours emprunter l'identité de l'utilisateur à partir du navigateur de l'utilisateur, mais si le navigateur est fermé, le script ne peut plus causer de dommages. L'indicateur secure garantit que les jetons ne peuvent pas être envoyés via des connexions non sécurisées - SSL/TLS est obligatoire
  2. Définir le domaine racine dans le cookie sur domain=example.com, par exemple, garantit que le cookie est accessible à travers tous les sous-domaines. Ainsi, différentes applications et serveurs au sein de l'entreprise peuvent utiliser les mêmes jetons. La connexion est requise une seule fois

Comment valider le jeton?

Les jetons sont généralement des jetons JWT. Généralement, le contenu du jeton n'est pas secret. Par conséquent, ils ne sont généralement pas cryptés. Si le chiffrement est requis (peut-être parce que certaines informations confidentielles sont également transmises dans le jeton), il existe une spécification distincte JWE. Même si le cryptage n'est pas requis, nous devons garantir l'intégrité des jetons. Personne (utilisateur ou attaquant) ne devrait être en mesure de modifier les jetons. S'ils le font, le serveur devrait pouvoir détecter cela et refuser toutes les demandes avec les jetons falsifiés. Pour garantir cette intégrité, les jetons JWT sont signés numériquement à l'aide d'un algorithme tel que HmacSHA256. Afin de générer cette signature, une clé secrète est requise. Le serveur d'autorisation possédera et protégera le secret. Chaque fois que l'API du serveur d'autorisation est appelée pour valider un jeton, le serveur d'autorisation recalculera le HMAC sur le jeton transmis. Si cela ne correspond pas à l'entrée HMAC, cela donne une réponse négative. Les jetons JWT sont renvoyés ou stockés dans un format codé Base64.

Toutefois, pour chaque appel d'API sur le serveur de ressources, le serveur d'autorisations n'est pas impliqué dans la validation du jeton. Le serveur de ressources peut mettre en cache les jetons émis par le serveur d'autorisation. Le serveur de ressources peut utiliser une grille de données en mémoire (à savoir. Redis) ou, si tout ne peut pas être stocké dans la RAM, une base de données basée sur LSM (à savoir Riak avec Level DB) pour stocker les jetons.

Pour chaque appel d'API, le serveur de ressources vérifierait son cache.

  1. Si le jeton d'accès n'est pas présent dans la mémoire cache, les API doivent renvoyer un message de réponse approprié et un code de réponse 401 de sorte que le SPA puisse rediriger l'utilisateur vers une page appropriée où il serait demandé à l'utilisateur de se reconnecter.

  2. Si le jeton d'accès est valide mais a expiré (remarque, les jetons JWT contiennent entre autres le nom d'utilisateur et la date d'expiration), les API doivent renvoyer un message de réponse approprié et un code de réponse 401 de sorte que le SPA puisse invoquer une API de serveur de ressources appropriée. renouveler le jeton d'accès avec le jeton d'actualisation (avec les en-têtes de cache appropriés). Le serveur invoquerait ensuite le serveur d'autorisation avec le jeton d'accès, le jeton d'actualisation et le secret du client, et le serveur d'autorisation pourrait renvoyer le nouvel accès et les jetons d'actualisation qui se retrouveraient éventuellement dans le SPA (avec les en-têtes de cache appropriés). Ensuite, le client doit réessayer la demande d'origine. Tout cela sera géré par le système sans intervention de l'utilisateur. Un cookie distinct pourrait être créé pour stocker le jeton d'actualisation, similaire au jeton d'accès, mais avec la valeur appropriée pour l'attribut Path, de sorte que le jeton d'actualisation n'accompagne pas toutes les demandes, mais qu'il ne soit disponible que dans les demandes de renouvellement.

  3. Si le jeton d'actualisation n'est pas valide ou a expiré, les API doivent renvoyer un message de réponse et un code de réponse 401 appropriés, de sorte que le SPA puisse rediriger l'utilisateur vers une page appropriée sur laquelle il serait demandé à l'utilisateur de se reconnecter.

Pourquoi avons-nous besoin de deux jetons - un jeton d'accès et un jeton d'actualisation?

  1. Les jetons d'accès ont généralement une courte période de validité, par exemple 30 minutes. Le jeton d'actualisation a généralement une période de validité plus longue, soit 6 mois. Si le jeton d'accès est compromis, l'attaquant peut emprunter l'identité de l'utilisateur victime uniquement tant que le jeton d'accès est valide. L'attaquant ne disposant pas du secret client, il ne peut pas demander au serveur d'autorisation un nouveau jeton d'accès. L'attaquant peut toutefois demander le renouvellement du jeton au serveur de ressources (comme dans la configuration ci-dessus, la demande de renouvellement passe par le serveur de ressources pour éviter de stocker le secret du client dans un navigateur), mais étant donné les autres étapes effectuées, il est peu probable et le serveur peut prendre des mesures de protection supplémentaires en fonction de l'adresse IP.

  2. Si cette courte période de validité du jeton d'accès aide le serveur d'autorisation à révoquer les jetons émis des clients, si nécessaire. Le serveur d'autorisation peut également conserver un cache des jetons émis. Les administrateurs du système peuvent ensuite, si nécessaire, marquer les jetons de certains utilisateurs comme révoqués. À l'expiration du jeton d'accès, lorsque le serveur de ressources accédera au serveur d'autorisations, l'utilisateur sera obligé de se connecter à nouveau.

Qu'en est-il de la CSRF?

  1. Afin de protéger l'utilisateur de CSRF, nous pouvons suivre l'approche suivie dans des cadres tels que Angular (comme expliqué dans la Angular HttpClient documentation) où le serveur doit envoyer un cookie autre que HttpOnly (en d’autres termes, un cookie lisible) contenant une valeur imprévisible unique pour cette session particulière. Il s’agit d’une valeur aléatoire forte sur le plan cryptographique. Le client lira alors toujours le cookie et l’enverra. la valeur dans un en-tête HTTP personnalisé (sauf GET & HEAD qui ne sont supposées avoir aucune logique de changement d'état. Remarque: CSRF ne peut rien lire dans l'application Web cible en raison de la même politique d'origine) que le serveur puisse vérifier la valeur de l'en-tête et du cookie, les formulaires inter-domaines ne pouvant ni lire le cookie ni définir d'en-tête personnalisé, dans le cas de demandes CSRF, la valeur de l'en-tête personnalisé sera manquante et le serveur pourra détecter l'attaque

  2. Pour protéger l’application de la connexion CSRF, vérifiez toujours l’en-tête referer et acceptez les demandes uniquement lorsque referer est un domaine approuvé. Si l'entête referer est absente ou s'il s'agit d'un domaine ne figurant pas sur la liste blanche, rejetez simplement la demande. Lorsque vous utilisez SSL/TLS, referrer est généralement présent. Pages de renvoi (principalement informatives et ne contenant ni formulaire de connexion ni contenu sécurisé) peuvent être un peu détendues et autoriser les requêtes avec en-tête manquant referer

  3. TRACE La méthode HTTP doit être bloquée sur le serveur car elle peut être utilisée pour lire le cookie httpOnly.

  4. Définissez également l'en-tête Strict-Transport-Security: max-age=<expire-time>; includeSubDomains Pour n'autoriser que les connexions sécurisées afin d'empêcher toute intervention de man-in-the-middle d'écraser les cookies CSRF d'un sous-domaine

  5. De plus, le paramètre SameSite mentionné ci-dessus devrait être utilisé

Enfin, SSL/TLS est obligatoire pour toutes les communications. Les versions TLS inférieures à 1.1 ne sont pas acceptables pour la conformité PCI/DSS. Des suites de chiffrement appropriées doivent être utilisées pour assurer la confidentialité du transfert et le chiffrement authentifié. En outre, les jetons d'accès et d'actualisation doivent être mis sur liste noire dès que l'utilisateur clique explicitement sur "Déconnexion" pour éviter toute possibilité d'utilisation abusive de jetons.

Références

  1. RFC 6749 - OAuth2.
  2. Feuille de triche OWASP JWT
  3. brouillon SameSite Cookie IETF
  4. préfixes de cookies
  5. RFC 6265 - Cookie
3
Saptarshi Basu