Sécurité des schémas d'authentification REST

228

Contexte:

Je conçois le schéma d'authentification pour un service Web REST. Cela n'a pas "vraiment" besoin d'être sécurisé (c'est plus un projet personnel) mais je veux le rendre aussi sécurisé que possible comme une expérience d'exercice / d'apprentissage. Je ne veux pas utiliser SSL car je ne veux pas les tracas et, surtout, les frais d'installation.

Ces questions SO étaient particulièrement utiles pour me lancer:

Je pense utiliser une version simplifiée de l'authentification d' Amazon S3 (j'aime OAuth mais cela semble trop compliqué pour mes besoins). J'ajoute un nonce généré aléatoirement , fourni par le serveur, à la demande, pour empêcher les attaques par rejeu.

Pour arriver à la question:

S3 et OAuth s'appuient sur la signature de l'URL de demande avec quelques en-têtes sélectionnés. Aucun d'eux ne signe le corps de la requête pour les requêtes POST ou PUT. N'est-ce pas vulnérable à une attaque d'homme au milieu, qui conserve l'URL et les en-têtes et remplace le corps de la demande par toutes les données souhaitées par l'attaquant?

Il semble que je puisse me prémunir contre cela en incluant un hachage du corps de la demande dans la chaîne qui est signée. Est-ce sécurisé?

dF.
la source
6
Amazon S3 peut inclure un Content-MD5 dans la chaîne d'en-tête pour empêcher l'attaque MITM que vous décrivez.
laz
8
MD5 est une fonction de hachage très faible et son utilisation est découragée depuis de nombreuses années: en.wikipedia.org/wiki/MD5 . Utilisez SHA2 de nos jours. MD5 est du rouge à lèvres sur un cochon en crise d'identité.
Henrik
6
Startcom fournit des certificats SSL gratuits qui n'émettent pas d'avertissements de certificat dans les principaux navigateurs
Platon
5
@SeanKAnderson (rant: je trouve absurde la façon dont les gens parlent de 99,99999% s lorsque Internet est assiégé par des agences d'espionnage qui ont déjà automatisé BEAUCOUP d'attaques en 2008 - c'est une façon si étrange de traiter un vrai problème - "Naaah, ce ne sera pas un problème; pour que ma grand-mère ne puisse pas le pirater"
Henrik
2
@Plato Je recommanderais LetsEncrypt ces jours-ci pour des
certificats

Réponses:

168

Une réponse précédente ne mentionnait SSL que dans le contexte du transfert de données et ne couvrait pas réellement l'authentification.

Vous vous posez vraiment des questions sur l'authentification sécurisée des clients de l'API REST. À moins que vous n'utilisiez l'authentification client TLS, SSL seul n'est PAS un mécanisme d'authentification viable pour une API REST. SSL sans client authc authentifie uniquement le serveur , ce qui n'est pas pertinent pour la plupart des API REST car vous voulez vraiment authentifier le client .

Si vous n'utilisez pas l'authentification client TLS, vous devrez utiliser quelque chose comme un schéma d'authentification basé sur un résumé (comme le schéma personnalisé d'Amazon Web Service) ou OAuth 1.0a ou même l'authentification HTTP Basic (mais sur SSL uniquement).

Ces schémas authentifient que la demande a été envoyée par quelqu'un attendu. TLS (SSL) (sans authentification client) garantit que les données envoyées via le câble restent intacts. Ce sont des préoccupations distinctes mais complémentaires.

Pour ceux qui sont intéressés, j'ai développé une question SO sur les schémas d'authentification HTTP et leur fonctionnement .

Les Hazlewood
la source
16
Exactement. La seule chose que SSL vérifie en ce qui concerne votre API est que l'appel dont il traite n'a pas été gâché en cours de route. L'API n'a toujours aucune idée de qui lui parle ou s'ils devraient ou non y avoir accès.
Tim Gautier
1
Bonne réponse. Je recommande aussi avoir un regard sur ces excellentes ressources .. owasp.org/index.php/Web_Service_Security_Cheat_Sheet et owasp.org/index.php/REST_Security_Cheat_Sheet (PROJET)
dodgy_coder
2
Juste un point mineur, mais l'utilisation de SSL a également l'avantage supplémentaire d'empêcher l'écoute clandestine et les attaques d'homme au milieu.
dodgy_coder
@Les Hazlewood Pourriez-vous expliquer comment l'authentification HTTP Basic sur Https peut aider à déterminer à quel serveur il parle?
Printemps
@Les Hazlewood ici, je l'ai posé dans une question; TNX stackoverflow.com/questions/14043397/...
Printemps
60

REST signifie travailler avec les standards du web, et le standard pour un transfert "sécurisé" sur le web est SSL. Tout le reste va être un peu génial et nécessiter des efforts de déploiement supplémentaires pour les clients, qui devront disposer de bibliothèques de chiffrement.

Une fois que vous vous êtes engagé sur SSL, rien n'est vraiment nécessaire pour l'authentification en principe. Vous pouvez à nouveau utiliser les normes Web et utiliser l'authentification HTTP de base (nom d'utilisateur et jeton secret envoyés avec chaque demande) car c'est beaucoup plus simple qu'un protocole de signature élaboré et toujours efficace dans le contexte d'une connexion sécurisée. Il vous suffit de vous assurer que le mot de passe ne dépasse jamais le texte brut; donc si le mot de passe est jamais reçu via une connexion en texte brut, vous pouvez même désactiver le mot de passe et envoyer un e-mail au développeur. Vous devez également vous assurer que les informations d'identification ne sont enregistrées nulle part à la réception, tout comme vous ne connecteriez pas un mot de passe normal.

HTTP Digest est une approche plus sûre car elle empêche la transmission du jeton secret; au lieu de cela, c'est un hachage que le serveur peut vérifier à l'autre extrémité. Bien que cela puisse être exagéré pour les applications moins sensibles si vous avez pris les précautions mentionnées ci-dessus. Après tout, le mot de passe de l'utilisateur est déjà transmis en texte brut lors de sa connexion (à moins que vous ne fassiez un cryptage JavaScript sophistiqué dans le navigateur), ainsi que ses cookies à chaque demande.

Notez qu'avec les API, il est préférable pour le client de passer des jetons - des chaînes générées aléatoirement - au lieu du mot de passe avec lequel le développeur se connecte au site Web. Le développeur doit donc pouvoir se connecter à votre site et générer de nouveaux jetons pouvant être utilisés pour la vérification de l'API.

La principale raison d'utiliser un jeton est qu'il peut être remplacé s'il est compromis, alors que si le mot de passe est compromis, le propriétaire peut se connecter au compte du développeur et faire tout ce qu'il veut avec. Un autre avantage des jetons est que vous pouvez émettre plusieurs jetons aux mêmes développeurs. Peut-être parce qu'ils ont plusieurs applications ou parce qu'ils veulent des jetons avec différents niveaux d'accès.

(Mis à jour pour couvrir les implications de la connexion SSL uniquement.)

mahemoff
la source
3
Vous pourriez obtenir un certificat SSL GoDaddy pour 30 $ par an, je pense. J'ai été choqué de voir combien les certificats SSL Verisign coûtent (600 $ par an ou quelque chose si je me souviens bien?) Mais l'option GoDaddy est parfaitement réalisable.
Brian Armstrong
19
Sauf si vous utilisez l'authentification mutuelle SSL / TLS et que le certificat utilisé par l'utilisateur / client est approuvé par le serveur, vous n'avez pas authentifié l'utilisateur auprès du serveur / de l'application. Vous devrez faire quelque chose de plus pour authentifier l'utilisateur auprès du serveur / de l'application.
Pauld
5
Ryan: Le cryptage SSL de nos jours nécessite une quantité de puissance de traitement assez petite par rapport à ce que vous utiliseriez pour générer une réponse avec un cadre d'application Web comme Django ou Rails, etc.
Cameron Walsh
4
les certificats de startcom sont gratuits et largement reconnus. cacert.org est une alternative ouverte avec moins de reconnaissance
Dima Tisnek
17
Cela ne répond pas à la question, qui concerne l'authentification.
Sam Stainsby
8

Ou vous pouvez utiliser la solution connue à ce problème et utiliser SSL. Les certificats auto-signés sont gratuits et c'est un projet personnel non?

wowest
la source
2
Les certificats auto-signés sont gratuits, mais AFAIK vous avez toujours besoin d'une adresse IP statique.
dF.
8
@dF il n'y a aucune exigence d'avoir une adresse IP statique, sauf pour certaines exigences de licence de certificats commerciaux payés.
Chris Marisic
Si vous contrôlez les magasins de certificats des deux côtés (clients et serveur), cela peut être une option viable mais ... la gestion et la distribution des certificats sont probablement beaucoup plus complexes en production qu'en environnement de développement. Assurez-vous de comprendre la complexité de cette alternative avant de vous y engager.
aled
5

Si vous avez besoin du hachage du corps comme l'un des paramètres de l'URL et que cette URL est signée via une clé privée, alors une attaque man-in-the-middle ne pourrait remplacer le corps par du contenu qui générerait le même hachage. Facile à faire avec les valeurs de hachage MD5 maintenant au moins et lorsque SHA-1 est cassé, eh bien, vous obtenez l'image.

Pour protéger le corps contre la falsification, vous auriez besoin d'exiger une signature du corps, qu'une attaque de l'homme du milieu serait moins susceptible de casser car ils ne connaîtraient pas la clé privée qui génère la signature .

ZaDDaZ
la source
9
Trouver une chaîne qui générera le même hachage md5 que le contenu valide peut être beaucoup plus facile qu'il ne devrait l'être, mais trouver une mauvaise version de contenu valide qui hache à la même valeur est toujours d'une difficulté prohibitive. C'est pourquoi md5 n'est plus utilisé pour les hachages de mot de passe, mais est toujours utilisé pour vérifier les téléchargements.
Tim Gautier
1

N'oubliez pas que vos suggestions empêchent les clients de communiquer avec le serveur. Ils doivent comprendre votre solution innovante et crypter les données en conséquence, ce modèle n'est pas si bon pour l'API publique (sauf si vous êtes amazon \ yahoo \ google ..).

Quoi qu'il en soit, si vous devez crypter le contenu du corps, je vous suggère de vérifier les normes et solutions existantes comme:

Cryptage XML (norme W3C)

Sécurité XML

LiorH
la source