web-dev-qa-db-fra.com

Comment sécuriser mon REST API?

En détail, voici le problème:

Je crée une application Android, qui consomme mon REST API sur le back-end. Je dois commencer par créer une API d'enregistrement et de connexion. Après avoir cherché avec Google pendant un certain temps, j'ai l'impression qu'il n'y a que deux approches que je peux adopter.

  • Lors de l'inscription, j'utilise https et j'obtiens les informations d'identification de l'utilisateur; enregistrez-le dans ma base de données contre le nom d'utilisateur (côté serveur). Lors de la connexion, j'utilise à nouveau https, et je demande les informations d'identification de l'utilisateur; vérifiez le mot de passe haché sur la base de données et renvoyez-lui un ID de session, que je prévois de ne jamais expirer à moins qu'il ne se déconnecte. De plus, tout autre appel d'API (GET/POST) que l'utilisateur fait, sera accompagné de cet ID de session afin que je puisse vérifier l'utilisateur.

Mais dans l'approche ci-dessus, je suis obligé d'utiliser https pour tout appel d'API, sinon Je suis vulnérable à Man in The Middle Attack , c'est-à-dire que si quelqu'un renifle mon ID de session, il peut reconstruire des requêtes GET/POST similaires que je ne voudrais pas.Ai-je raison avec l'hypothèse ci-dessus?

  • La deuxième option consiste à suivre le chemin de Amazon Web Services , où j'utilise l'authentification par clé publique/privée. Lorsqu'un utilisateur s'inscrit, j'utilise une API https pour enregistrer ses informations d'identification dans la base de données . À partir de là, j'utilise le mot de passe haché de l'utilisateur comme clé privée. Tout autre appel d'API que l'utilisateur effectue aura un blob haché de l'URL de demande à l'aide de la clé privée de l'utilisateur. Côté serveur, je reconstruis le hachage à l'aide de la clé privée enregistrée. Si le hachage est une correspondance, je laisse l'utilisateur faire sa tâche, sinon je rejette. Dans cette option, je dois utiliser https uniquement pour l'API d'enregistrement. REST peut continuer http.

Mais ici, l'inconvénient est que je suis obligé d'héberger mon API d'enregistrement dans un répertoire virtuel séparé (j'utilise IIS et je ne suis pas sûr de pouvoir héberger les API http et https dans le même répertoire virtuel). Par conséquent, je suis obligé de développer l'API d'enregistrement dans un fichier de projet distinct.Encore une fois, ai-je raison avec l'hypothèse ci-dessus?

Edit: J'utilise ASP.NET MVC4 pour créer l'API Web.

La raison pour laquelle j'hésite à utiliser https pour tous mes REST Les appels d'API sont que je pense que ce n'est pas léger et crée plus de charge utile réseau, ce qui n'est peut-être pas mieux adapté à une application mobile. Un chiffrement/déchiffrement supplémentaire et une négociation supplémentaire requise peuvent affecter davantage la durée de vie de la batterie d'un mobile?Ou n'est-ce pas significatif?

Laquelle des deux approches ci-dessus suggéreriez-vous?

PS: Nous sommes allés avec Https partout, et c'était la meilleure décision. Plus de cela sur mon blog .

84
noob Mama

J'irais avec SSL/TLS partout (puisque vous contrôlez les deux côtés, forcer TLS 1.2 devrait être possible). Son utilisation est relativement simple et vous bénéficiez gratuitement de nombreuses fonctionnalités de sécurité. Par exemple, si vous n'utilisez pas SSL, vous devrez vous soucier des attaques de relecture.

Si vous êtes préoccupé par les performances, assurez-vous que la reprise de session est prise en charge par le serveur et le client. Cela rend les poignées de main plus tard beaucoup moins chères. Étant donné que la prise de contact est assez coûteuse en SSL par rapport au cryptage des données réelles, cela réduit considérablement la charge globale.

Si vous utilisez HTTP 2, vous pouvez même envoyer plusieurs demandes sur une seule connexion, de cette façon, vous évitez le TCP et la surcharge de prise de contact SSL sur les demandes ultérieures).

54
CodesInChaos

Je recommande d'utiliser OAuth. Vous devriez certainement le lire si vous ne le connaissez pas. En plus, vous pouvez utiliser des fournisseurs d'identité tiers, afin que vos utilisateurs puissent utiliser leurs comptes Google/Windows Live/etc. pour votre application, épargnant l'enregistrement.

Même si vous souhaitez déployer votre propre infrastructure d'authentification, je ne recommande pas d'utiliser des sessions qui n'expirent pas. La session doit expirer après un temps d'inactivité suffisant, sinon cela donne plus de place à l'exploitation (détournement de session par exemple).

23

Cela dépend à quel point il doit être sécurisé . Chaque fois que vous complexifiez la solution, vous risquez également de laisser un trou béant. Il est préférable d'utiliser une sorte de module d'autorisation et d'authentification standard de l'industrie.

Vous irez probablement bien, tant que vous êtes:

  • crypter le mot de passe (avec quelque chose comme AES ou Blowfish)
  • saler le mot de passe
  • envoi des données via HTTPS

Une alternative est OAuth.

Si quelqu'un veut vous pirater suffisamment, il trouvera toujours un moyen. Le secret est d'augmenter le temps et les efforts nécessaires pour que cela ne vaille pas la peine de le faire. Par conséquent, si vous ne disposez pas d'énormes quantités de données clients et/ou financières, et que vous n'êtes pas une entreprise de haut niveau, une implémentation de sécurité standard comme celle ci-dessus devrait convenir.

4
Dan Blows

Vous ne serez jamais sûr à 100% que votre API est sécurisée.

La raison principale en est que vous remettez probablement à vos clients/utilisateurs un binaire qui fonctionne simplement. Alors, ils ont tout le temps du monde pour disséquer ce binaire pour y rechercher des clés/secrets, utilisé pour s'authentifier en toute sécurité sur votre serveur API. Le point de terminaison de l'API client est le point le plus faible, car ils possèdent le périphérique sur lequel votre binaire s'exécute, ils peuvent donc manipuler les certificats que leur périphérique considère comme valides ou non.

Un exemple clair de ce dont je parle est cet article ("Un tutoriel pour l'ingénierie inverse de l'API privée de votre logiciel: pirater votre canapé"). Et je voudrais finaliser cette réponse en citant l'un des derniers paragraphes:

Est-il possible d'empêcher complètement l'utilisation d'une API privée par des clients tiers? Je ne pense pas. L'utilisation de l'épinglage SSL empêcherait de renifler dans les demandes d'API en utilisant une technique de proxy transparent simple comme décrit précédemment. En fin de compte, même si vous obscurcissez le binaire, un pirate motivé avec des ressources et du temps sera toujours en mesure de rétroconcevoir le binaire de l'application et d'obtenir la clé privée/le certificat. Je pense que l'hypothèse selon laquelle le point de terminaison client est sécurisé est intrinsèquement erronée. Un client API est un point faible.

2
knocte

Dans JEE, nous avons la notion de sécurité gérée par conteneur. Dans ce cas, j'ai configuré mes services reposants pour utiliser l'authentification de base, qui utilise par défaut l'authentification par mot de passe HTTP par rapport à un domaine configuré sur le serveur d'applications. Cela contourne la nécessité d'un formulaire HTML pour se connecter ou la complexité du déploiement de certificats côté client.

L'application suppose simplement qu'il y aurait un principal d'utilisateur et peut-être d'autres données telles que les détails d'identification qui sont transmises avec la demande. Cela inclut les API reposantes.

Dans ma configuration, j'ai implémenté un module d'authentification du serveur JASPIC OAuth2 [ Source ] qui stocke le jeton OAuth crypté symétriquement là où le réside dans le serveur qui a également une durée de vie limitée dans le cookie et l'utiliser comme authentification pour l'application.

En faisant ce qui précède, je garde l'application éloignée de la sémantique d'authentification et en prime lorsque je veux effectuer des tests d'intégration fonctionnelle en utilisant Selenium, je suis en mesure de rétrograder pour utiliser des mots de passe HTTP au lieu d'avoir un test complexe qui se connecte à un OAuth fournisseur tout le temps.

De plus, j'utiliserai toujours SSL pour garantir au moins que votre transport est sécurisé. Ne pas utiliser SSL ajoute simplement trop de complexité dans le traitement des attaques courantes à votre application.

Rappelez-vous que c'est JEE mais que les mécanismes peuvent être appliqués à n'importe quelle technologie.

2
Archimedes Trajano

HTTPS uniquement est un must.

Comme vous contrôlez à la fois l'application et l'API, j'implémenterais l'épinglage de certificat. L'épinglage de certificat peut être vaincu, mais c'est un bon moyen de dissuasion contre l'inspecteur occasionnel.

Vous pouvez ajouter une autre couche avec Payload Encryption. Cela vient au prix de la construction d'un solide processus de distribution et de rotation des clés.

Si votre application utilise des jetons d'accès ou des cookies de session pour l'autorisation de certaines API, assurez-vous qu'elles expirent. J'observe si souvent des jetons au porteur qui n'expirent pas pendant des jours, des mois ou jamais.

Règle d'or: Un O/S mobile est un environnement hostile. Traitez-le avec soin et manque de confiance.

1
rustyMagnet

Je pense que ce n'est pas léger et crée plus de charge utile réseau

Cela a un certain impact sur la latence - donc si vous avez besoin de traiter les données par ordre de 10 secondes de millisecondes, cela peut être une considération. Mais même en 2012, un matériel très basique pouvait gérer les frais généraux de calcul avec un impact négligeable.

qui peut ne pas convenir le mieux à une application mobile

Alors ce qui précède n'est pas un problème.

0
symcbean