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 plutôt un projet personnel) mais je veux le rendre aussi sûr que possible en tant qu’exercice / expérience d’apprentissage. Je ne veux pas utiliser SSL car je ne veux pas les tracas et, surtout, les frais de configuration.

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

  • Authentification RESTful
  • Meilleures pratiques pour sécuriser une API / un service Web REST
  • Exemples des meilleures API Web SOAP / REST / RPC? Et pourquoi les aimez-vous? Et qu’est-ce qui ne va pas avec eux?

Je pense à utiliser une version simplifiée de l’authentification Amazon S3 (j’aime bien 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 de relecture.

Pour arriver à la question:

S3 et OAuth comptent tous deux sur la signature de l’URL de la requête avec quelques en-têtes sélectionnés. Ni l’un ni l’autre ne signent le corps de requête pour les requêtes POST ou PUT. N’est-ce pas vulnérable à une attaque de type «man-in-the-middle», qui conserve l’URL et les en-têtes et remplace le corps de la requête par les données souhaitées par l’attaquant?

Il semble que je puisse m’en protéger en incluant un hachage du corps de la requête dans la chaîne signée. Est-ce sécurisé?

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

    Vous vous demandez vraiment comment authentifier en toute sécurité les clients de l’API REST. À moins d’utiliser l’authentification du 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 du client TLS, vous devrez utiliser quelque chose comme un schéma d’authentification basé sur Digest (comme le schéma personnalisé d’Amazon Web Service) ou OAuth 1.0a ou même une authentification HTTP Basic (mais uniquement sur SSL).

    Ces schémas authentifient que la demande a été envoyée par quelqu’un attendu. TLS (SSL) (sans authentification du client) garantit que les données envoyées via le réseau restnt intactes. Ce sont des préoccupations distinctes, mais complémentaires.

    Pour ceux que cela intéresse, j’ai développé une question SO sur les schémas d’authentification HTTP et leur fonctionnement .

    REST signifie travailler avec les standards du Web et le standard pour le transfert “sécurisé” sur le Web est SSL. Tout le rest sera plutôt funky et nécessitera un effort de déploiement supplémentaire pour les clients, qui devront disposer de bibliothèques de chiffrement.

    Une fois que vous vous êtes engagé sur SSL, il n’y a vraiment rien de compliqué à faire pour une authentification de principe. Vous pouvez à nouveau utiliser les standards Web et utiliser l’authentification HTTP Basic (nom d’utilisateur et jeton secret envoyés avec chaque requête) car elle est beaucoup plus simple qu’un protocole de signature élaboré et toujours 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 désactiver le mot de passe et envoyer le développeur par courrier. Vous devez également vous assurer que les informations d’identification ne sont pas consignées n’importe où à la réception, tout comme vous ne consigneriez pas un mot de passe régulier.

    HTTP Digest est une approche plus sûre car elle empêche le transfert du jeton secret; au lieu de cela, c’est un hachage que le serveur peut vérifier à l’autre extrémité. Bien que vous ayez pris les précautions mentionnées ci-dessus, cela peut être excessif pour des applications moins sensibles. Après tout, le mot de passe de l’utilisateur est déjà transmis en clair lorsqu’il se connecte (sauf si vous utilisez un cryptage JavaScript sophistiqué dans le navigateur), ainsi que ses cookies à chaque demande.

    Notez qu’avec les API, il est préférable que le client passe des jetons (chaînes générées aléatoirement) au lieu du mot de passe que le développeur 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 des 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 des niveaux d’access différents.

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

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

    Si vous avez besoin du hachage du corps comme l’un des parameters de l’URL et que cette URL soit signée via une clé privée, alors une attaque de type intermédiaire ne pourrait remplacer le corps que par un contenu qui générerait la clé. même hachage Facile à faire avec les valeurs de hachage MD5 maintenant et au moment où SHA-1 est cassé, vous obtenez l’image.

    Pour sécuriser le corps contre la falsification, vous devez exiger une signature du corps, ce qui serait moins probable pour une attaque de type «man-in-the-middle», car ils ne connaissent pas la clé privée qui génère la signature. .

    En fait, l’authentification S3 originale permet de signer le contenu, mais avec une signature MD5 faible. Vous pouvez simplement appliquer leur pratique facultative d’inclure un en-tête Content-MD5 dans le 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

    N’oubliez pas que vos suggestions compliquent la communication 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 (sauf si vous êtes 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 les solutions existantes telles que:

    Chiffrement XML (norme W3C)

    Sécurité XML