image
image
image
image
image
image

401 jeton oauth non autorisé

Interdit, non autorisé, ou quoi d’autre ?

Supposons que votre API Web soit protégée et qu’un client tente d’y accéder sans les informations d’identification appropriées. Comment gérez-vous ce scénario ? Très probablement, vous savez que vous devez renvoyer un code d’état HTTP. Mais quel est le plus approprié ? Devrait-il être

ou ? Ou peut-être autre chose ?

Comme d’habitude, cela dépend 🙂 de . Cela dépend du scénario spécifique et aussi du niveau de sécurité que vous souhaitez fournir. Allons un peu plus loin.

Si vous préférez, vous pouvez regarder une vidéo sur le même sujet :

API Web et codes d'état HTTP

Avant d'entrer dans le sujet spécifique, jetons un coup d'œil rapide à la raison d'être des codes d'état HTTP en général. La plupart des API Web sont inspirées du paradigme REST. Bien que la grande majorité d'entre eux n'implémentent pas réellement REST, ils suivent généralement quelques conventions RESTful en ce qui concerne les codes d'état HTTP.

Le principe de base de ces conventions est qu’un code d’état renvoyé dans une réponse doit informer le client de ce qui se passe et de ce que le serveur attend du client qu’il fasse ensuite . Vous pouvez respecter ce principe en répondant aux questions suivantes :

  • Y a-t-il un problème ou non ?
  • S’il y a un problème, de quel côté se trouve-t-il ? Côté client ou côté serveur ?
  • S’il y a un problème, que doit faire le client ?

Il s’agit d’un principe général qui s’applique à tous les codes d’état HTTP. Par exemple, si le client reçoit un code d'

état, il sait qu'il n'y a pas eu de problème avec sa demande et s'attend à ce que la représentation de la ressource demandée figure dans le corps. Si le client reçoit un code d'état, il sait qu'il n'y a pas eu de problème avec sa demande, mais la représentation de la ressource ne figure pas dans le corps de la réponse. De même, lorsque le client reçoit un code d'état, il sait qu'il s'agit d'un problème côté serveur et le client ne peut rien faire pour l'atténuer.

En résumé, la réponse de votre API Web doit fournir au client suffisamment d'informations pour se rendre compte comment il peut avancer opportunément.

Prenons le cas où un client tente d'appeler une API protégée. Si le client fournit les informations d’identification appropriées (par exemple, un jeton d’accès valide), sa demande est acceptée et traitée. Que se passe-t-il lorsque le client n’a pas les informations d’identification appropriées ? Quel code d’état votre API doit-elle renvoyer lorsqu’une requête n’est pas légitime ? Quelles informations doit-il restituer et comment garantir la meilleure expérience de sécurité ?

Heureusement, dans la sécurité OAuth contexte, vous avez quelques lignes directrices. Bien sûr, vous pouvez les utiliser même si vous n'utilisez pas OAuth pour sécuriser votre API.

« Le principe de base derrière les conventions de code d’état REST est qu’un code d’état doit informer le client de ce qui se passe et de ce que le serveur attend du client qu’il fasse ensuite »

Tweetez ceci

Quand utiliser 400 Bad Request ?

Commençons par un cas simple : un client appelle votre API protégée, en omettant un paramètre obligatoire. Dans ce cas, votre API doit répondre avec un code d’état

. En fait, si ce paramètre est requis, votre API ne peut même pas traiter la demande du client. La demande du client est mal formée.

Votre API doit renvoyer le même code d’état même si le client fournit un paramètre non pris en charge ou répète le même paramètre plusieurs fois dans sa demande. Dans les deux cas, la demande du client n'est pas attendu et devrait être refusé .

Conformément au principe général discuté ci-dessus, le client doit être en mesure de comprendre ce qu’il doit faire pour résoudre le problème. Vous devez donc ajouter dans le corps de votre réponse ce qui n'allait pas avec la demande du client. Vous pouvez fournir ces détails dans le format que vous préférez, tel que texte simple, XML, JSON, etc. Cependant, l’utilisation d’un format standard tel que celui proposé par les spécifications Détails du problème pour les API HTTP serait plus appropriée pour permettre une gestion uniforme des problèmes entre les clients.

Par exemple, si votre client appelle votre API avec une valeur vide pour le paramètre requis

, l’API peut répondre avec la réponse suivante :

Quand utiliser 401 non autorisé ?

Supposons maintenant que le client appelle votre API protégée avec une requête bien formée, mais sans informations d'identification valides. Par exemple, dans le contexte OAuth, cela peut tomber dans un dans les cas suivants :

  • Un jeton d’accès est manquant.
  • Un jeton d’accès a expiré, est révoqué, mal formé ou n’est pas valide pour d’autres raisons.

Dans les deux cas, le code d’état approprié avec lequel répondre est

. Dans un esprit de collaboration mutuelle entre le client et l’API, la réponse doit inclure un indice sur la façon d’obtenir une telle autorisation. Cela se présente sous la forme de l’en-tête avec le schéma d’authentification spécifique à utiliser. Par exemple, dans le cas d’OAuth2, la réponse doit ressembler à ce qui suit :

Vous devez utiliser le

schéma et fournir le paramètre pour indiquer l’ensemble des ressources que l’API protège.

Si la demande du client n'inclut aucun jeton d'accès, démontrant qu'il ne savait pas que l'API est protégée, la réponse de l'API ne doit pas inclure d'autres informations.

D'autre part, si le demande un jeton d’accès expiré, la réponse de l’API peut inclure la raison de l’accès refusé, comme le montre l’exemple suivant :

Quand utiliser 403 interdit ?

Explorons maintenant un autre cas. Supposons, par exemple, que votre client envoie une demande de modification d’un document et fournisse un jeton d’accès valide à l’API. Toutefois, ce jeton n'inclut ni n'implique aucune autorisation ou portée permettant au client d'effectuer l'action souhaitée.

Dans ce cas, votre API doit répondre avec un code d’état

. Avec ce code d’état, votre API indique au client que les informations d’identification qu’il a fournies (par exemple, le jeton d’accès) sont valides, mais qu’il a besoin des privilèges appropriés pour effectuer l’action demandée.

Pour aider le client à comprendre ce qu’il doit faire ensuite, votre API peut inclure les privilèges nécessaires dans sa réponse. Par exemple, selon les directives OAuth2, votre API peut inclure Informations sur l’étendue manquante pour accéder à la ressource protégée.

Essayez gratuitement la plateforme d’authentification la plus puissante.

Commencez →

Lorsque vous planifiez la façon de répondre aux demandes de vos clients, gardez toujours la sécurité à l'esprit.

Comment gérer les détails de la réponse

L’une des principales préoccupations en matière de sécurité est d’éviter de fournir des informations utiles à des attaquants potentiels . En d’autres termes, le renvoi d’informations détaillées dans les réponses de l’API aux tentatives d’accès aux ressources protégées peut constituer un risque de sécurité.

Par exemple, supposons que votre API renvoie un code d’état

avec une description d’erreur telle que . Dans ce cas, il donne des informations sur le jeton lui-même à un attaquant potentiel. Il en va de même lorsque votre API répond avec un code d’état et signale l’étendue ou le privilège manquant.

En d’autres termes, le partage de ces informations peut améliorer la collaboration entre le client et le serveur, selon le principe de base du paradigme REST. Cependant, les mêmes informations peuvent être utilisées par des attaquants malveillants pour élaborer leur stratégie d’attaque .

Étant donné que ces informations supplémentaires sont facultatives à la fois pour les spécifications HTTP et les directives relatives aux jetons de porteur OAuth2, vous devriez peut-être réfléchir attentivement avant de les partager. Le principe de base de l’échange de ces renseignements supplémentaires devrait être fondé sur la réponse à la question suivante : en quoi le client se comporterait-il différemment s’il recevait plus d’information ?

Par exemple, dans le cas d'une réponse avec un code d

'état, le comportement du client change-t-il lorsqu'il sait que son jeton est expiré ou révoqué ? Dans tous les cas, il doit demander un nouveau token. Ainsi, l'ajout de ces informations ne change pas le comportement du client.

Différent est le cas avec

. En informant votre client qu’il a besoin d’une autorisation spécifique, votre API lui fait apprendre ce qu’il doit faire ensuite, c’est-à-dire demander cette autorisation supplémentaire. Si votre API ne fournit pas ces informations supplémentaires, elle se comportera différemment car elle ne sait pas quoi faire pour accéder à cette ressource.

Ne le faites pas savoir au client...

Supposons maintenant que votre client tente d’accéder à une ressource à laquelle il NE DOIT PAS accéder du tout, par exemple, parce qu’elle appartient à un autre utilisateur. Quel code d’état votre API doit-elle renvoyer ? Doit-il renvoyer un code d’état

ou un code d’état ?

Vous pourriez être tenté de retourner un code d’état

de toute façon. Mais, en fait, vous ne pouvez pas suggérer d'autorisation manquante, car ce client n'a aucun moyen d'accéder à cette ressource. Ainsi, le code d’état ne donne aucune information utile réelle. Vous pensez peut-être que le renvoi d’un code d’état a du sens dans ce cas. Après tout, le appartient à un autre utilisateur, la demande doit donc provenir d’un autre utilisateur.

Cependant, étant donné que cette ressource ne doit pas être atteinte par le client actuel, la meilleure option consiste à la masquer. Le fait d'informer le client (et en particulier l'utilisateur qui se cache derrière) de l'existence d'une ressource peut entraîner des références IDOR (Insecure Direct Object References), une vulnérabilité de contrôle d'accès basée sur la connaissance des ressources auxquelles vous ne devez pas accéder. Par conséquent, dans ces cas, votre API doit répondre avec un code d’état

. Il s’agit d’une option fournie par la spécification HTTP :

un serveur d’origine qui souhaite « cacher » l’existence actuelle d’une ressource cible interdite PEUT répondre à la place avec un code d’état 404 (Not Found).

Par exemple, il s'agit de la stratégie adoptée par GitHub lorsque vous n'avez aucune autorisation pour accéder à un dépôt. Cette approche permet d’éviter qu’un attaquant ne tente pour accéder à nouveau à la ressource avec une stratégie légèrement différente.

Comment gérer les demandes incorrectes Lorsqu’un

client envoie une demande incorrecte, vous savez que vous devez répondre avec un code d’état

. Vous pourriez être tenté d'analyser l'exactitude de la demande avant d'évaluer les informations d'identification du client. Vous ne devez pas le faire pour plusieurs raisons :
  • en évaluant les informations d'identification du client avant la validité de la demande, vous évitez que votre API ne traite des demandes qui ne sont pas autorisées à s'y trouver.
  • Un attaquant potentiel pourrait déterminer à quoi devrait ressembler une requête sans être authentifié, avant même d’obtenir ou de voler un jeton d’accès légitime.

De plus, considérez que dans les infrastructures avec une passerelle API, les identifiants du client seront évalués au préalable par la passerelle elle-même, qui ne sait pas du tout quels paramètres l'API attend.

Les mesures de sécurité décrites ici doivent être appliquées dans l’environnement de production. Bien entendu, dans l’environnement de développement, votre API peut fournir toutes les informations dont vous avez besoin pour pouvoir diagnostiquer les causes d’un échec d’autorisation.

Tout

au long de cet article, vous avez appris que :

  • est le code d’état à retourner lorsque la forme de la requête client n’est pas celle attendue par l’API.
  • est le code d’état à renvoyer lorsque le client ne fournit aucune information d’identification ou des informations d’identification non valides.
  • est le code d’état à renvoyer lorsqu’un client dispose d’informations d’identification valides, mais de privilèges insuffisants pour effectuer une action sur une ressource.

Vous avez également appris que certains problèmes de sécurité peuvent survenir lorsque votre API expose des détails que des attaquants malveillants peuvent exploiter. Dans ces cas, vous pouvez adopter une stratégie plus restreinte en incluant juste les détails nécessaires dans le corps de la réponse ou même en utilisant le code d’état

au lieu de ou .

L’aide-mémoire suivant résume ce que vous avez appris :

À propos de l’auteur

Andrea Chiarelli

Principal Developer Advocate

J’ai plus de 20 ans d’expérience en tant qu’ingénieur logiciel et auteur technique. NET to Node.js, Angular to React, SOAP vers les API REST, etc.

Au cours des dernières années, je me suis concentré sur la simplification de l'expérience des développeurs avec l'identité et les sujets connexes, en particulier dans l'écosystème .NET.

Voir le profil