Question

Lors de la conception d'une API ou d'un service REST, existe-t-il des bonnes pratiques établies pour gérer la sécurité (authentification, autorisation, gestion des identités) ?

Lorsque vous créez une API SOAP, vous utilisez WS-Security comme guide et il existe de nombreuses publications sur le sujet.J'ai trouvé moins d'informations sur la sécurisation des points de terminaison REST.

Bien que je comprenne que REST n'a intentionnellement pas de spécifications analogues à WS-*, j'espère que les meilleures pratiques ou les modèles recommandés ont émergé.

Toute discussion ou lien vers des documents pertinents serait très apprécié.Si cela est important, nous utiliserions WCF avec des messages sérialisés POX/JSON pour nos API/services REST construits à l'aide de la version 3.5 du .NET Framework.

Était-ce utile?

La solution

Comme l'a dit Tweakt, Amazon S3 est un bon modèle avec lequel travailler.Leurs signatures de requêtes possèdent certaines fonctionnalités (telles que l'incorporation d'un horodatage) qui aident à se prémunir contre la réexécution de requêtes accidentelles et malveillantes.

L’avantage de HTTP Basic est que pratiquement toutes les bibliothèques HTTP le prennent en charge.Vous devrez bien sûr exiger SSL dans ce cas, car l'envoi de mots de passe en clair sur le net est presque universellement une mauvaise chose.Basic est préférable à Digest lors de l'utilisation de SSL, car même si l'appelant sait déjà que les informations d'identification sont requises, Digest nécessite un aller-retour supplémentaire pour échanger la valeur occasionnelle.Avec Basic, les appelants envoient simplement les informations d'identification la première fois.

Une fois l’identité du client établie, l’autorisation n’est en réalité qu’un problème de mise en œuvre.Cependant, vous pouvez déléguer l'autorisation à un autre composant doté d'un modèle d'autorisation existant.Encore une fois, l'avantage de Basic est que votre serveur se retrouve avec une copie en texte brut du mot de passe du client que vous pouvez simplement transmettre à un autre composant de votre infrastructure si nécessaire.

Autres conseils

Il n’existe pas de normes pour REST autres que HTTP.Il existe des services REST établis.Je vous suggère d'y jeter un coup d'œil et d'avoir une idée de leur fonctionnement.

Par exemple, nous avons emprunté de nombreuses idées au service S3 REST d'Amazon pour développer le nôtre.Mais nous avons choisi de ne pas utiliser le modèle de sécurité plus avancé basé sur les signatures de requêtes.L'approche la plus simple est l'authentification HTTP Basic sur SSL.Vous devez décider ce qui fonctionne le mieux dans votre situation.

De plus, je recommande vivement le livre Services Web RESTful d'O'reilly.Il explique les concepts de base et fournit quelques bonnes pratiques.Vous pouvez généralement prendre le modèle fourni et le mapper à votre propre application.

Vous voudrez peut-être aussi jeter un oeil à OAuth, un protocole ouvert émergent pour l'autorisation basée sur des jetons ciblant spécifiquement les API http.

C’est très similaire à l’approche adoptée par Flickr et souviens-toi du lait API "rest" (pas nécessairement de bons exemples d'API reposantes, mais de bons exemples de l'approche basée sur les jetons).

Il existe une excellente liste de contrôle sur GitHub:

Authentification

  • Ne réinventez pas la roue en matière d'authentification, de génération de jetons et de stockage de mots de passe.Utilisez les normes.

  • Utiliser Max Retry et les fonctionnalités de prison dans la connexion.

  • Utilisez le cryptage sur toutes les données sensibles.

JWT (jeton Web JSON)

  • Utilisez une clé aléatoire compliquée (JWT Secret) pour rendre le forçage brutal du jeton très difficile.

  • N'extrayez pas l'algorithme de la charge utile.Forcez l'algorithme dans le backend (HS256 ou RS256).

  • Faire expirer le jeton (TTL, RTTL) le plus court possible.

  • Ne stockez pas de données sensibles dans le JWT charge utile, elle peut être décodée facilement.

OAuth

  • Validez toujours redirect_uri côté serveur pour autoriser uniquement les URL sur liste blanche.

  • Essayez toujours d'échanger contre du code et non des jetons (ne permettez pas response_type=token).

  • Utilisez le paramètre d'état avec un hachage aléatoire pour éviter CSRF sur le OAuth processus d'authentification.

  • Définissez la portée par défaut et validez les paramètres de portée pour chaque application.

Accéder

  • Limiter les requêtes (Throttling) pour éviter les attaques DDoS/force brute.

  • Utilisez HTTPS côté serveur pour éviter MITM (Man In The Middle Attack)

  • Utiliser HSTS en-tête avec SSL pour éviter les attaques SSL Strip.

Saisir

  • Utilisez la méthode HTTP appropriée en fonction de l'opération : GET (lire), POST (créer), PUT/PATCH (remplacer/mettre à jour), et DELETE (pour supprimer un enregistrement) et répondez avec 405 Method Not Allowed si la méthode demandée n'est pas appropriée pour la ressource demandée.

  • Valider le type de contenu sur demande Accept en-tête (Content Négociation) pour autoriser uniquement votre format pris en charge (par ex. application/xml, application/json, etc) et répondez avec 406 Not Acceptable réponse si elle ne correspond pas.

  • Valider content-type des données publiées comme vous l'acceptez (par ex. application/x-www-form-urlencoded, multipart/form-data, application/json, etc).

  • Validez les entrées de l'utilisateur pour éviter les vulnérabilités courantes (par ex.XSS, injection SQL, exécution de code à distance, etc.).

  • N'utilisez aucune donnée sensible (identifiants, mots de passe, jetons de sécurité ou clés API) dans l'URL, mais utilisez des Authorization entête.

  • Utiliser un service API Gateway pour activer la mise en cache, Rate Limit politiques (par ex.Quota, Spike Arrest, Concurrent Rate Limit) et déployez les ressources API de manière dynamique.

Traitement

  • Vérifiez si tous les points de terminaison sont protégés derrière l'authentification pour éviter un processus d'authentification interrompu.

  • L’ID de ressource propre à l’utilisateur doit être évité.Utilisez /me/orders au lieu de /user/654321/orders.

  • N'incrémentez pas automatiquement les identifiants.Utilisez plutôt l'UUID.

  • Si vous analysez des fichiers XML, assurez-vous que l'analyse des entités n'est pas activée pour éviter XXE (attaque d'entité externe XML).

  • Si vous analysez des fichiers XML, assurez-vous que l'expansion d'entité n'est pas activée pour éviter une bombe Billion Laughs/XML via une attaque d'expansion d'entité exponentielle.

  • Utilisez un CDN pour les téléchargements de fichiers.

  • Si vous traitez une énorme quantité de données, utilisez les Workers et les Queues pour traiter autant que possible en arrière-plan et renvoyer une réponse rapide pour éviter le blocage HTTP.

  • N'oubliez pas de tourner le DÉBOGUER mode désactivé.

Sortir

  • Envoyer X-Content-Type-Options: nosniff entête.

  • Envoyer X-Frame-Options: deny entête.

  • Envoyer Content-Security-Policy: default-src 'none' entête.

  • Supprimer les en-têtes d'empreintes digitales - X-Powered-By, Server, X-AspNet-Version etc.

  • Forcer content-type pour votre réponse, si vous revenez application/json alors le type de contenu de votre réponse est application/json.

  • Ne renvoyez pas de données sensibles telles que les informations d'identification, les mots de passe et les jetons de sécurité.

  • Renvoie le code d'état approprié en fonction de l'opération effectuée.(par exemple. 200 OK, 400 Bad Request, 401 Unauthorized, 405 Method Not Allowed, etc).

Je suis un peu surpris que SSL avec les certificats clients n'ait pas encore été mentionné.Certes, cette approche n’est réellement utile que si l’on peut compter sur une communauté d’utilisateurs identifiée par des certificats.Mais un certain nombre de gouvernements/entreprises les délivrent à leurs utilisateurs.L'utilisateur n'a pas à se soucier de créer une autre combinaison nom d'utilisateur/mot de passe, et l'identité est établie à chaque connexion afin que la communication avec le serveur puisse être entièrement sans état, aucune session utilisateur n'est requise.(Cela ne veut pas dire que toutes les autres solutions mentionnées nécessitent des sessions)

Tout le monde dans ces réponses a négligé le véritable contrôle/autorisation d’accès.

Si, par exemple, vos API/services Web REST concernent la publication/obtention de dossiers médicaux, vous souhaiterez peut-être définir une politique de contrôle d'accès indiquant qui peut accéder aux données et dans quelles circonstances.Par exemple:

  • les médecins peuvent OBTENIR le dossier médical d’un patient avec lequel ils entretiennent une relation de soins
  • personne ne peut PUBLIER des données médicales en dehors des heures de pratique (par ex.9 à 5)
  • les utilisateurs finaux peuvent OBTENIR les dossiers médicaux qu'ils possèdent ou les dossiers médicaux des patients dont ils sont le tuteur
  • les infirmières peuvent METTRE À JOUR le dossier médical d'un patient appartenant à la même unité que l'infirmière.

Afin de définir et de mettre en œuvre ces autorisations précises, vous devrez utiliser un langage de contrôle d'accès basé sur les attributs appelé XACML, l'eXtensible Access Control Markup Language.

Les autres normes ici concernent les éléments suivants :

  • OAuth :identifiant.fédération et délégation d’autorisation par ex.laisser un service agir en mon nom sur un autre service (Facebook peut publier sur mon Twitter)
  • SAML :fédération d'identité / web SSO.SAML dépend en grande partie de l'identité de l'utilisateur.
  • Normes WS-Security / WS-* :ceux-ci se concentrent sur la communication entre les services SOAP.Ils sont spécifiques au format de messagerie au niveau de l'application (SOAP) et traitent des aspects de la messagerie, par ex.fiabilité, sécurité, confidentialité, intégrité, atomicité, événementiel...Aucun ne couvre le contrôle d'accès et tous sont spécifiques à SOAP.

XACML est indépendant de la technologie.Il peut être appliqué aux applications Java, .NET, Python, Ruby...services Web, API REST, etc.

Voici des ressources intéressantes :

J'ai utilisé OAuth plusieurs fois et j'ai également utilisé d'autres méthodes (BASIC/DIGEST).Je suggère de tout cœur OAuth.Le lien suivant est le meilleur tutoriel que j'ai vu sur l'utilisation d'OAuth :

http://hueniverse.com/oauth/guide/

L'un des meilleurs articles que j'ai jamais vu concernant la sécurité en ce qui concerne REST est disponible sur 1 goutte de pluie.Les API MySpace utilisent également OAuth pour la sécurité et vous avez un accès complet à leurs canaux personnalisés dans le code RestChess, avec lequel j'ai beaucoup exploré.Cela a été démo chez Mix et vous pouvez trouver la publication ici.

Merci pour les excellents conseils.Nous avons fini par utiliser un en-tête HTTP personnalisé pour transmettre un jeton d'identité du client au service, en préparation de l'intégration de notre API RESTful avec le prochain framework Zermatt Identity de Microsoft.J'ai décrit le problème ici et notre solution ici.j'ai aussi pris modifierles conseils et acheté Services Web RESTful - un très bon livre si vous créez une API RESTful de quelque nature que ce soit.

OWASP (Open Web Application Security Project) propose des aide-mémoire couvrant tous les aspects du développement d'applications Web.Ce projet est une source d’informations très précieuse et fiable.Concernant les services REST vous pouvez vérifier ceci : https://www.owasp.org/index.php/REST_Security_Cheat_Sheet

Je recommanderais OAuth 2/3.Vous pouvez trouver plus d'informations sur http://oauth.net/2/

J'ai beaucoup cherché sur la sécurité reposante de ws et nous avons également fini par utiliser un jeton via un cookie du client au serveur pour authentifier les demandes.J'ai utilisé Spring Security pour autoriser les requêtes en service, car je devais authentifier et autoriser chaque requête en fonction des politiques de sécurité spécifiées déjà présentes dans la base de données.

Le fait que le monde SOAP soit assez bien couvert par les normes de sécurité ne signifie pas qu'il est sécurisé par défaut.En premier lieu, les normes sont très complexe.La complexité n'est pas une très bonne amie des vulnérabilités de sécurité et de mise en œuvre telles que Attaques d'encapsulation de signature XML sont endémiques ici.

Quant à l'environnement .NET, je ne vais pas beaucoup aider, mais "Créer des services Web avec Java" (une brique avec ~ 10 auteurs) m'a aidé beaucoup dans la compréhension de l'architecture de sécurité WS-* et, surtout, de ses bizarreries.

REST lui-même n'offre aucune norme de sécurité, mais des éléments comme OAuth et SAML deviennent rapidement les normes dans ce domaine.Cependant, l’authentification et l’autorisation ne représentent qu’une petite partie de ce que vous devez prendre en compte.De nombreuses vulnérabilités connues liées aux applications Web s'appliquent en grande partie aux API REST.Vous devez prendre en compte la validation des entrées, le piratage de session, les messages d'erreur inappropriés, les vulnérabilités internes des employés, etc.C'est un grand sujet.

Je souhaite ajouter (conformément à stinkeymatt), la solution la plus simple serait d'ajouter des certificats SSL à votre site.En d’autres termes, assurez-vous que votre URL est HTTPS://.Cela couvrira la sécurité de votre transport (pour votre argent).Avec les URL RESTful, l'idée est de rester simple (contrairement à WS* security/SAML), vous pouvez utiliser oConnexion Auth2/openID ou même Basic Auth (dans des cas simples).Mais vous aurez toujours besoin de SSL/HTTPS.Veuillez vérifier la sécurité de l'ASP.NET Web API 2 ici : http://www.asp.net/web-api/overview/security (Articles et vidéos)

Comme @Nathan s'est retrouvé avec un simple en-tête HTTP, et certains avaient dit OAuth2 et certificats SSL côté client.L'essentiel est le suivant...votre API REST ne devrait pas avoir à gérer la sécurité car cela devrait vraiment sortir du cadre de l'API.

Au lieu de cela, une couche de sécurité doit être placée au-dessus, qu'il s'agisse d'un en-tête HTTP derrière un proxy Web (une approche courante comme SiteMinder, Zermatt ou même Apache HTTPd), ou aussi compliquée que OAuth 2.

L'essentiel est que les requêtes doivent fonctionner sans aucune interaction de l'utilisateur final.Il suffit de s'assurer que la connexion à l'API REST est authentifiée.En Java EE, nous avons la notion de userPrincipal qui peut être obtenu sur un HttpServletRequest.Il est également géré dans le descripteur de déploiement qu'un modèle d'URL peut être sécurisé afin que le code de l'API REST n'ait plus besoin d'être vérifié.

Dans le monde WCF, j'utiliserais ServiceSecurityContext.Current pour obtenir le contexte de sécurité actuel.Vous devez configurer votre application pour exiger une authentification.

Il y a une exception à la déclaration que j'ai eue ci-dessus et c'est l'utilisation d'un nonce pour empêcher les rediffusions (qui peuvent être des attaques ou quelqu'un soumettant simplement les mêmes données deux fois).Cette partie ne peut être gérée que dans la couche application.

Pour la sécurité des applications Web, vous devriez jeter un œil à OWASP (https://www.owasp.org/index.php/Main_Page) qui fournit des aide-mémoire pour diverses attaques de sécurité.Vous pouvez intégrer autant de mesures que possible pour sécuriser votre application.En ce qui concerne la sécurité des API (autorisation, authentification, gestion des identités), il existe plusieurs méthodes comme déjà mentionné (Basic, Digest et OAuth).Il y a des trous dans OAuth1.0, vous pouvez donc utiliser OAuth1.0a (OAuth2.0 n'est pas largement adopté en raison de problèmes liés à la spécification)

Cela fait un moment mais la question est toujours d'actualité, même si la réponse a peut-être un peu changé.

Une passerelle API serait une solution flexible et hautement configurable.J'ai testé et utilisé KONG pas mal et j'ai vraiment aimé ce que j'ai vu.KONG fournit sa propre API REST d'administration que vous pouvez utiliser pour gérer les utilisateurs.

Express-gateway.io est plus récent et est également une passerelle API.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top