web-dev-qa-db-fra.com

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

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 davantage un projet personnel), mais je souhaite le rendre aussi sûr que possible. possible en tant qu’exercice/expérience d’apprentissage. Je ne veux pas utiliser SSL car je ne veux pas de problèmes et, surtout, des frais de mise en place.

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

Je pense utiliser une version simplifiée de authentification Amazon S (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 dépendent de la signature de l'URL de la requête avec quelques en-têtes sélectionnés. Aucun d'entre eux ne signe le corps de la requête pour POST ou requêtes PUT. N’est-il pas vulnérable à une attaque par interception, qui conserve l’URL et les en-têtes et remplace le corps de la requête par les données que l’attaquant souhaite?

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

224
dF.

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

Vous vous interrogez vraiment sur l'authentification sécurisée REST clients API. Sauf si vous utilisez l'authentification client TLS, SSL seul N’EST PAS un mécanisme d’authentification viable pour une REST. SSL sans l’authentification du client authentifie uniquement le serveur , ce qui n’est pas pertinent. pour la plupart des API REST parce que vous voulez vraiment authentifier le client .

Si vous n'utilisez pas l'authentification du client TLS, vous devrez utiliser un schéma d'authentification basé sur Digest (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 une personne attendue. TLS (SSL) (sans authentification du client) garantit que les données envoyées sur le réseau restent non marquées. Ce sont des préoccupations distinctes, mais complémentaires.

Pour ceux que cela intéresse, j'ai développé une SO question concernant schémas d'authentification HTTP et leur fonctionnement) .

166
Les Hazlewood

REST signifie travailler avec les standards du Web et le standard pour les transferts "sécurisés" sur le Web est SSL. Tout le reste va être génial et nécessitera un effort de déploiement supplémentaire pour les clients, qui devront disposer de bibliothèques de chiffrement disponibles.

Une fois que vous vous êtes engagé sur SSL, rien de plus sophistiqué n'est requis en principe pour l'authentification. 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), ce qui est beaucoup plus simple qu’un protocole de signature élaboré et qui reste efficace dans le contexte d’une connexion sécurisée. Vous devez simplement vous assurer que le mot de passe ne dépasse jamais le texte brut. Par conséquent, si le mot de passe est reçu via une connexion en texte brut, vous pouvez même le désactiver et envoyer un courrier électronique au développeur. Vous devez également vous assurer que les informations d'identification ne sont enregistrées à aucun endroit lors de la réception, tout comme vous ne vous connecteriez pas avec 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 bout. Bien que cela puisse être excessif pour des 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 la connexion (sauf si vous utilisez un cryptage JavaScript sophistiqué dans le navigateur), ainsi que leurs cookies à chaque demande.

Notez qu'avec les API, il est préférable que le client transmette des jetons - des chaînes générées de manière aléatoire - au lieu du mot de passe que le développeur enregistre sur le 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 ce qu'il veut avec. Un autre avantage des jetons est que vous pouvez en envoyer plusieurs 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.

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

60
mahemoff

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?

8
wowest

Si vous avez besoin du hachage du corps comme l’un des paramètres de l’URL et que cette URL soit signée via une clé privée, une attaque de type intermédiaire n’est en mesure de remplacer le corps que par un contenu qui générerait le message. même hash. Facile à faire avec les valeurs de hachage MD5 maintenant au moins et quand SHA-1 est cassé, eh bien, vous obtenez l'image.

Pour sécuriser le corps contre toute manipulation, il vous faudrait une signature du corps, ce qu'une attaque d'infiltration aurait moins de chance de briser car elle ne connaît pas la clé privée qui génère la signature. .

5
ZaDDaZ

En fait, l'authentification S3 d'origine autorise la signature du contenu, bien qu'avec une signature MD5 faible. Vous pouvez simplement appliquer leur pratique facultative consistant à inclure un en-tête Content-MD5 dans HMAC (chaîne à signer).

http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html

Leur nouveau schéma d'authentification v4 est plus sécurisé.

http://docs.aws.Amazon.com/general/latest/gr/signature-version-4.html

3
djsadinoff

N'oubliez pas que vos suggestions empêchent les clients de communiquer avec le serveur. Ils ont besoin de comprendre votre solution innovante et de chiffrer les données en conséquence, ce modèle n’est pas si bon pour les API publiques (à moins que vous ne soyez Amazon\yahoo\google ..).

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

Cryptage XML (standard W3C)

Sécurité XML

1
LiorH