Les meilleures Pratiques pour sécuriser une API REST / service web [fermé]
lors de la conception d'une API ou d'un service REST, y a-t-il des pratiques exemplaires établies en matière de sécurité (Authentification, autorisation, Gestion de l'identité) ?
lors de la construction d'une API SOAP vous avez WS-sécurité comme guide et beaucoup de littérature existe sur le sujet. J'ai trouvé moins d'informations sur la sécurisation des points de repos.
bien que je comprenne que le REST n'a pas intentionnellement de spécifications analogues à WS-* j'espère que les meilleures pratiques ou les modèles recommandés ont émergé.
toute discussion ou tout lien vers des documents pertinents serait très apprécié. Si cela importe, nous utiliserions WCF avec des messages Pox / JSON sérialisés pour nos API/Services REST construits avec v3.5 of the .NET Framework.
18 réponses
comme tweakt l'a dit, Amazon S3 est un bon modèle pour travailler avec. Leurs signatures de requête ont certaines caractéristiques (comme l'intégration d'une estampille temporelle) qui aident à se prémunir contre la répétition accidentelle et malveillante de la requête.
ce qu'il y a de bien avec HTTP Basic, c'est que pratiquement toutes les bibliothèques HTTP le supportent. Vous aurez, bien sûr, besoin D'Exiger SSL dans ce cas parce que l'envoi de mots de passe en clair sur le net est presque universellement une mauvaise chose. De base est préférable à Digest lors de L'utilisation de SSL parce que même si l'appelant sait déjà que des justificatifs d'identité sont nécessaires, Digest nécessite un aller-retour supplémentaire pour échanger la valeur nonce. Avec Basic, les appelants envoient simplement les justificatifs d'identité la première fois.
une fois l'identité du client établie, l'autorisation n'est qu'un problème de mise en œuvre. Cependant, vous pourriez déléguer l'autorisation à d'autres composantes à un modèle d'autorisation. Encore une fois, la chose agréable à propos de base voici votre serveur se termine avec une copie en clair du mot de passe du client que vous pouvez simplement transmettre à un autre composant de votre infrastructure au besoin.
il n'y a pas de normes de repos autres que HTTP. Il y a des services de repos établis là-bas. Je vous suggère de jeter un coup d'oeil et de vous familiariser avec leur fonctionnement.
par exemple, nous avons emprunté beaucoup d'idées du service de repos S3 D'Amazon en développant notre propre. Mais nous avons choisi de ne pas utiliser le modèle de sécurité plus avancé basé sur les signatures de requête. L'approche la plus simple est HTTP Basic auth sur SSL. Vous devez décider ce qui fonctionne le mieux dans votre situation.
aussi, je recommande fortement le livre RESTful Web Services de O'Reilly. Il explique les concepts de base et fournit certaines pratiques exemplaires. Vous pouvez généralement prendre le modèle qu'ils fournissent et de l'associer à votre propre application.
vous pouvez également jeter un oeil à outh , un protocole ouvert émergent pour l'autorisation basée sur des tokens ciblant spécifiquement les API http.
Il est très similaire à l'approche adoptée par flickr et remember the milk "repos" api (pas nécessairement de bons exemples de restful api, mais de bons exemples de la base de jeton d'approche).
je suis un peu surpris que SSL avec des certificats clients n'ait pas encore été mentionné. Accordé, cette approche n'est vraiment utile que si vous pouvez compter sur la communauté des utilisateurs sont identifiés par des certificats. Mais un certain nombre de gouvernements/entreprises les émettent à leurs utilisateurs. L'utilisateur n'a pas à se soucier de créer encore une autre combinaison nom d'utilisateur / mot de passe, et l'identité est établie sur chaque connexion de sorte que la communication avec le serveur peut être totalement apatride, Non sessions utilisateur nécessaires. (Ne pas sous-entendre qu'une ou toutes les autres solutions mentionnées nécessitent des sessions)
tout le monde dans ces réponses a négligé le vrai contrôle d'accès / autorisation.
si, par exemple, vos services APIs / web repos concernent L'affichage / la mise à jour des dossiers médicaux, vous pouvez vouloir définir la Politique de contrôle d'accès sur 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 qui ils ont une relation de soins
- personne ne peut poster données médicales en dehors des heures de pratique (p. ex. 9 à 5)
- les utilisateurs finals 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 qui appartient à la même unité que l'infirmière.
afin de définir et de mettre en œuvre ces autorisations à grains fins, vous aurez besoin d'utiliser un langage de contrôle d'accès basé sur les attributs appelé XACML, le eXtensible Access Control Markup Language.
les autres normes sont les suivantes:
- OAuth: id. Fédération et délégation d'autorisation par exemple laisser un service agir en mon nom sur un autre service (Facebook peut poster sur Mon Twitter)
- SAML: la fédération d'identité / web SSO. SAML est très à propos de qui est l'utilisateur.
- WS-Security / WS - * standards: ceux-ci se concentrent sur la communication entre les services SOAP. Ils sont spécifiques au format de messagerie de niveau applicatif (SOAP) et traitent des aspects de la messagerie tels que la fiabilité, la sécurité, la confidentialité, l'intégrité, l'atomicité, le concours complet... Aucune ne couvre le contrôle d'accès et toutes sont spécifiques à SOAP.
XACML est la technologie de l'agnostique. Il peut être appliqué à java apps, .NET, Python, Ruby... services web, repos APIs, et plus.
les ressources suivantes sont intéressantes:
- l'OASIS XACML site web
- the NIST ABAC standard
il y a une grande liste de vérifications sur Github :
authentification
-
ne réinventez pas la roue dans L'authentification, la génération de tokens, le stockage de mots de passe. L'utilisation des normes.
-
utilisez
Max Retry
et les fonctionnalités jail dans Login. -
utiliser le cryptage sur tous les données sensibles.
JWT (JSON Web Token)
-
utilisez une touche aléatoire compliquée (Secret JWT) pour rendre brute forçant le jeton très dur.
-
N'extrayez pas l'algorithme de la charge utile. Forcez l'algorithme dans le backend (HS256 ou RS256).
-
Faire jeton d'expiration (
TTL
,RTTL
) aussi court que possible. -
Ne pas stocker de données sensibles dans le
JWT
charge utile, il peut être décodé facilement.
OAuth
-
Toujours valider
redirect_uri
côté serveur pour autoriser uniquement dans la liste blanche des URLs. -
toujours essayer d'échanger pour le code et pas de jetons (ne pas autoriser
response_type=token
). -
utiliser le paramètre d'état avec un hachage aléatoire pour empêcher
CSRF
sur le processus d'authentificationOAuth
. -
définit la portée par défaut, et valide les paramètres de portée pour chaque application.
accès
-
limite demandes (étranglement) pour éviter les attaques DDoS / brute-force.
-
utilisez HTTPS du côté du serveur pour éviter MITM (Man In the Middle Attack)
-
utiliser
HSTS
en-tête avec SSL pour éviter l'attaque de bande SSL.
Entrée
-
utilisez la méthode HTTP appropriée selon la opération:
GET
(lire),POST
(créer),PUT/PATCH
(remplacer/mettre à jour), etDELETE
(supprimer un enregistrement), et répondre avec405 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 (négociation de contenu) pour autoriser seulement votre format soutenu (par exempleapplication/xml
,application/json
, etc) et répondre avec406 Not Acceptable
réponse si non égaler. -
valider
content-type
des données postées que vous acceptez (par ex.application/x-www-form-urlencoded
,multipart/form-data
,application/json
, etc). -
valider les entrées de L'utilisateur pour éviter les vulnérabilités communes (par exemple XSS, SQL-Injection, exécution de Code à distance, etc.).
-
N'utilisez pas de données sensibles (justificatifs d'identité, mots de passe, jetons de sécurité ou clés API) dans L'URL, mais utilisez l'en-tête standard
Authorization
. -
utiliser un service de passerelle API pour activer la mise en cache, les politiques
Rate Limit
(par exemple, Quota, arrêt de la pointe, limite de débit Concurrent) et déployer les ressources APIs de façon dynamique.
traitement
-
processus.
-
Utilisateur propre ID de ressource doit être évitée. Utilisation /me/commandes au lieu de /utilisateur/654321/commandes.
-
Ne pas l'auto-incrémentation de l'IDs. Utilisez UUID à la place.
-
si vous analysez des fichiers XML, assurez-vous que l'analyse par l'entité n'est pas activée pour éviter XXE (XML external entity attack).
-
Si vous analysez Fichiers XML, assurez-vous que l'expansion de l'entité n'est pas activée pour éviter la bombe milliards de rires/XML via une attaque exponentielle d'expansion de l'entité.
-
utilisez un CDN pour le téléchargement de fichiers.
-
si vous avez affaire à une énorme quantité de données, utilisez des travailleurs et des files d'attente pour traiter autant que possible en arrière-plan et répondre rapidement pour éviter le blocage HTTP.
-
N'oubliez pas pour désactiver le mode DEBUG .
Sortie
-
Envoyer
X-Content-Type-Options: nosniff
en-tête. -
Envoyer
X-Frame-Options: deny
en-tête. -
Envoyer
Content-Security-Policy: default-src 'none'
en-tête. -
enlever les en-têtes d'empreintes digitales -
X-Powered-By
,Server
,X-AspNet-Version
etc. -
Force
content-type
pour votre réponse, si vous le retourapplication/json
puis votre réponse de type de contenu estapplication/json
. -
ne retournez pas les données sensibles comme les justificatifs d'identité, les mots de passe, les jetons de sécurité.
-
retourner le code d'état approprié selon l'opération terminée. (par ex.
200 OK
,400 Bad Request
,401 Unauthorized
,405 Method Not Allowed
, etc).
j'ai utilisé OAuth quelques fois, et aussi 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 de OAuth:
L'un des meilleurs messages que j'ai jamais vu concernant la sécurité en ce qui concerne le repos est terminé à 1 goutte de pluie . L'API MySpace utilise également Vauth pour la sécurité et vous avez un accès complet à leurs canaux personnalisés dans le code RestChess, avec lequel j'ai fait beaucoup d'exploration. Cela a été démo à Mix et vous pouvez trouver l'affichage ici .
Merci pour l'excellent conseil. 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 Zermatt Identity framework de Microsoft. J'ai décrit le problème ici et notre solution ici . J'ai également pris tweakt 'S conseil et acheté RESTful Web Services - un très bon livre si vous construisez une API reposante.
OWASP (Open Web Application Security Project) a quelques feuilles de tricherie couvrant tous les aspects du développement D'Application Web. Ce projet constitue une source d'information très précieuse et fiable. En ce qui concerne les services de repos, vous pouvez cocher cette case: https://www.owasp.org/index.php/REST_Security_Cheat_Sheet
je recommande OAuth 2/3. Vous pouvez trouver plus d'informations à http://oauth.net/2/
le fait que le monde du SOAP soit assez bien couvert par des 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 un très bon ami de la sécurité et les vulnérabilités de mise en œuvre comme XML signature wrapping attacks sont endémiques ici.
quant à L'environnement. NET Je ne vais pas aider beaucoup, mais " construire 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, ses bizarreries.
j'ai cherché beaucoup sur la sécurité WS restful et nous avons aussi fini par utiliser token via cookie du client au serveur pour authentifier les requêtes . J'ai utilisé spring security pour autoriser les requêtes en service parce que je devais authentifier et autoriser chaque requête basée sur des politiques de sécurité spécifiées qui ont déjà été dans DB.
REST lui-même n'offre pas de normes de sécurité, mais des choses comme OAuth et SAML deviennent rapidement les normes dans cet espace. Cependant, l'authentification et l'autorisation sont seulement une petite partie de ce que vous devez considérer. Bon nombre des vulnérabilités connues liées aux applications web s'appliquent en grande partie aux autres API. Vous devez tenir compte de la validation des entrées, du craquage des sessions, des messages d'erreur inappropriés, des vulnérabilités internes des employés, etc. C'est un grand sujet.
je veux ajouter(en ligne avec 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 (bang for the buck). Avec RESTful url's, l'idée est de le garder simple (contrairement à WS* security/SAML), vous pouvez utiliser oAuth2/openID connect ou même L'Auth de base (dans les cas simples). Mais vous aurez toujours besoin de SSL/HTTPS. Veuillez vérifier ASP.NET sécurité de L'API Web 2 ici: http://www.asp.net/web-api/overview/security (Articles et vidéos)
comme @Nathan a fini avec ce qui est un simple en-tête HTTP, et certains avaient dit OAuth2 et les certificats SSL côté client. L'essentiel, c'est cela... votre API REST ne devrait pas avoir à gérer la sécurité car cela devrait être hors du champ D'application de l'API.
au lieu de cela, une couche de sécurité devrait être placée dessus, que ce soit un en-tête HTTP derrière un proxy web (une approche commune 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 avec l'utilisateur final. Il suffit de s'assurer que la connexion à L'API REST est authentifiée. En Java EE nous avons la notion d'un 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é de sorte que le reste du code de L'API n'a plus besoin de vérifier.
dans le monde de la FMC, j'utiliserais ServiceSecurityContext.Current
pour obtenir le courant contexte de sécurité. Vous devez configurer votre application pour exiger l'authentification.
il y a une exception à la déclaration que j'avais ci-dessus et c'est l'utilisation d'une nonce pour empêcher les replays (qui peut être des attaques ou quelqu'un qui soumet juste les mêmes données deux fois). Cette partie ne peut être traitée que dans la couche application.
pour la sécurité des applications Web, vous devriez jeter un oeil à OWASP ( https://www.owasp.org/index.php/Main_Page ), qui fournit des feuilles de Cheat 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é de L'API (autorisation, authentification, gestion de l'identité), il existe de multiples façons (Basic,Digest et OAuth). Il y a des trous de boucle dans OAuth1.0, donc vous pouvez utiliser OAuth1.0a (OAuth2.0 n'est pas largement adopté en raison de préoccupations liées à la spécification)
Cela fait longtemps, mais la question est toujours pertinente, bien que la réponse ait peut-être un peu changé.
une passerelle API serait une solution flexible et hautement configurable. J'ai testé et utilisé KONG un peu et vraiment aimé ce que j'ai vu. KONG fournit une API admin REST qui vous est propre et que vous pouvez utiliser pour gérer les utilisateurs.
Express-gateway.io est plus récent et est aussi une passerelle API.