Question:
Comment sécuriser mon API REST?
noob Mama
2012-09-09 13:01:01 UTC
view on stackexchange narkive permalink

En détail, voici le problème:

Je construis une application Android, qui consomme mon API REST sur le back-end. J'ai besoin de créer une API d'inscription et de connexion pour commencer. 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 identifiant de session, que je prévois de ne jamais expirer à moins qu'il ne se déconnecte. De plus, tous les autres appels API (GET / POST) que l'utilisateur effectue, seront accompagnés 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 identifiant de session, il peut reconstruire des requêtes GET / POST similaires dont je ne voudrais pas. Ai-je raison avec l'hypothèse ci-dessus?

  • La deuxième option consiste à suivre le chemin des Amazon Web Services, où j'utilise public / authentification par clé 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 effectué par l'utilisateur aura un objet blob haché de l'URL de la demande à l'aide de la clé privée de l'utilisateur. Côté serveur, je reconstruis le hachage en utilisant la clé privée enregistrée. Si le hachage est une correspondance, je laisse l'utilisateur faire sa tâche, sinon je le rejette. Dans cette option, je dois utiliser https uniquement pour l'API d'enregistrement. Le REST peut continuer sur http .

Mais ici, l'inconvénient est que je suis obligé d'héberger mon API d'inscription dans un répertoire virtuel distinct (j'utilise IIS et je ne sais pas si je peux 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?

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

La raison pour laquelle je suis réticent à utiliser https pour tous mes appels d'API REST est 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é pour une application mobile. Un cryptage / décryptage supplémentaire et une poignée de main supplémentaire requis 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 avons opté pour Https partout, et c'était la meilleure décision. Plus d'informations sur mon blog.

Je l'ai déjà vécu et il y a beaucoup de liens intéressants, mais rien de tout cela ne répond tout à fait à tous mes doutes ci-dessus!
Avez-vous évalué SSL? La partie la plus chère de SSL est la poignée de main, et vous en avez déjà besoin pour vous connecter. La poignée de main peut souvent être réutilisée pour des connexions ultérieures (reprise de session).
Lorsqu'ils considèrent HTTPS, les développeurs sont généralement plus préoccupés par les performances du serveur. En ce qui concerne les appareils clients, combien de demandes envoyez-vous par minute? Je ne pense pas que quelques demandes par minute feraient une différence.
Vous pouvez générer un jeton sécurisé au moment de la connexion et vous l'enverrez dans la demande.J'ai obtenu des détails icihttp: //skillrow.com/basic-security-in-rest-api/
Votre deuxième approche n'est pas sécurisée, elle ne fait rien pour empêcher les attaques de relecture.Vous allez avoir du mal à assurer la sécurité sans HTTPS sur tout.De plus, vos raisons d'éviter le HTTPS n'ont pas de sens, la surcharge supplémentaire de nos jours n'est pas suffisamment importante pour être préoccupée, certainement par rapport aux implications de sécurité de ne pas l'utiliser.
Sept réponses:
CodesInChaos
2012-09-09 15:25:21 UTC
view on stackexchange narkive permalink

J'irais avec SSL / TLS partout (puisque vous contrôlez les deux côtés, forcer TLS 1.2 devrait être faisable). C'est relativement simple à utiliser et vous bénéficiez de nombreuses fonctionnalités de sécurité gratuitement. 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 à la fois par le serveur et le client. Cela rend les poignées de main ultérieures beaucoup moins chères. La prise de contact étant assez chère 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 requêtes via une seule connexion, de cette façon vous éviter la surcharge complète de la négociation TCP et SSL sur les demandes ultérieures.

mais qu'en est-il de la charge utile du réseau? ne transférerais-je pas plus de données sur le fil si je l'utilisais pour toutes les actions? compte tenu de la bande passante limitée des téléphones portables, est-ce toujours une bonne idée pour une application interactive?
Il semble peu probable que la surcharge du réseau SSL soit pertinente. Mais si vous en doutez, * mesurez *. La poignée de main coûte quelques ko, la surcharge par paquet de quelques dizaines d'octets.
HTTP / 1.1 peut faire une série de requêtes sur une connexion, bien que de nombreux serveurs (et proxys, etc.) et certains clients ne le maintiennent pas ouvert s'ils sont inactifs pendant «trop longtemps», ce qui peut durer de quelques secondes à plusieurs heures; ce que HTTP / 2 ajoute, ce sont plusieurs requêtes * simultanées * / qui se chevauchent.
Zsombor Erdődy-Nagy
2012-09-09 13:38:51 UTC
view on stackexchange narkive permalink

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

Même si vous souhaitez créer le vôtre cadre d'authentification, je ne recommande pas d'utiliser des sessions qui n'expirent pas. La session devrait expirer après un temps d'inactivité suffisant, sinon cela donne plus de place à l'exploitation (piratage de session par exemple).

J'ai regardé dans OAuth, je vois que c'est utile lorsque je veux permettre aux utilisateurs de se connecter à mon application, avec Google / Windows / etc. identifiants. Mais ne devrais-je pas aussi leur donner le choix de s'inscrire uniquement pour mon application? De plus, je vois votre point sur le détournement de session, Intéressant, .. je n'y ai jamais pensé!
Vous pouvez également intégrer OAuth côté serveur, afin que vos utilisateurs puissent créer un compte uniquement pour votre application. Ce n'est pas seulement utile parce que vous pouvez utiliser des fournisseurs d'identité tiers, c'est aussi utile car c'est un cadre d'authentification assez bon et sophistiqué sur lequel vous pouvez compter. D'un autre côté, cela _peut_ être trop complexe pour une application simple, mais c'est à vous de décider.
Hmm .. btw, la raison pour laquelle j'ai pensé à ne pas expirer la session est que la plupart des applications comme Twitter et Pinterest n'ont pas d'option de déconnexion. Je suppose que la session n'expire jamais non plus.
+1 pour la recommandation OAuth. Cependant, je suis totalement en désaccord avec le commentaire concernant les sessions non expirées. Sur les plates-formes mobiles, les sessions non expirées sont idéales pour la plupart des applications. Ne forcez pas l'utilisateur à saisir un mot de passe à plusieurs reprises sur un clavier mobile (beurk! Non seulement c'est gênant, mais cela peut amener les utilisateurs à choisir des mots de passe plus faibles, ce qui nuit à la sécurité globale). Personnellement, je recommanderais d'utiliser une session non expirante comme un excellent moyen d'obtenir à la fois sécurité et commodité.
Il convient de mentionner que OAuth * doit * être effectué via un canal sécurisé, tel que HTTPS.Si vous utilisez OAuth sans HTTPS ou un autre canal sécurisé, toute la sécurité est compromise ...
Blowski
2012-09-09 13:19:21 UTC
view on stackexchange narkive permalink

Cela dépend du degré de sécurité dont il a besoin . Chaque fois que vous compliquez 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.

Tout ira probablement bien, tant que vous:

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

Une alternative est OAuth.

Si quelqu'un veut vous pirater assez mal, il trouvera toujours un moyen. Le secret est d'augmenter suffisamment le temps et les efforts nécessaires pour que quelqu'un ne le fasse pas. 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 premier plan, une mise en œuvre de sécurité standard comme celle ci-dessus devrait convenir.

Les mots de passe ne doivent jamais être chiffrés. Les mots de passe doivent toujours être hachés. AES et BLowfish ne conviennent pas pour le stockage des mots de passe. Vous avez besoin de PBKDF2, bcrypt, script. (Enfer, même une fonction de hachage md5 cassée est meilleure que AES pour le stockage des mots de passe.)
Archimedes Trajano
2014-07-08 11:15:52 UTC
view on stackexchange narkive permalink

Dans JEE, nous avons la notion de sécurité gérée par conteneur. Dans ce cas, j'ai configuré mes services de repos 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 évite le besoin 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 utilisateur principal et peut-être d'autres données telles que les détails d'identification qui sont transmis avec la requête. 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 qui est crypté symétriquement là où réside la clé dans le serveur qui a également une durée de vie limitée dans le cookie et utilisez-le comme authentification pour l'application.

En faisant ce qui précède, je garde l'application à l'écart de la sémantique d'authentification et en prime, lorsque je souhaite effectuer des tests d'intégration fonctionnelle avec Selenium, je suis en mesure de revenir à l'utilisation de mots de passe HTTP au lieu d'avoir un test complexe qui se connecte à un fournisseur OAuth tout le temps.

De plus, j'utiliserai toujours SSL pour m'assurer qu'au moins votre transport est sécurisé. Ne pas utiliser SSL ajoute simplement trop de complexité dans la gestion des attaques courantes de votre application.

Rappelez-vous qu'il s'agit de JEE, mais les mécanismes peuvent être appliqués à n'importe quelle technologie.

knocte
2016-07-02 13:13:46 UTC
view on stackexchange narkive permalink

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

La raison principale en est que vous remettez probablement un binaire à vos clients / utilisateurs qui fonctionne simplement. Ils ont donc tout le temps du monde pour disséquer ce binaire pour y rechercher des clés / secrets, utilisés 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 il possède l'appareil sur lequel s'exécute votre binaire, il peut donc manipuler les certificats que son appareil juge valides ou non.

Un exemple clair de ce que je ' Je parle de cet article ("Tutoriel pour la rétro-ingénierie 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 les demandes d'API à l'aide d'une simple technique de proxy transparent comme décrit précédemment. En fin de compte, même si vous obscurcissez le binaire, un hacker motivé avec quelques 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 du client est sécurisé est intrinsèquement erronée. Un client API est un point faible.

rustyMagnet
2016-07-18 18:16:51 UTC
view on stackexchange narkive permalink

Uniquement HTTPS est un must.

En contrôlant à 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 se fait au prix de la création 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 d'API spécifiques, assurez-vous qu'ils expirent. J'observe si souvent des jetons porteurs qui n'expirent pas avant des jours, des mois ou jamais.

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

symcbean
2019-11-09 03:59:29 UTC
view on stackexchange narkive permalink

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

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

qui n'est peut-être pas le mieux adapté pour une application mobile

Ensuite, le ci-dessus n'est pas un problème.

cela ne semble pas répondre à la question mais fait des commentaires sur une partie du message.
la question est basée sur un faux prédicat - que tout le monde semble avoir ignoré.
la réponse acceptée contient un paragraphe entier sur le problème de performance


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...