web-dev-qa-db-fra.com

Connectez-vous sans HTTPS, comment sécuriser?

Pour une application Web, lorsque le protocole HTTPS n'est pas disponible par mesure de sécurité, est-il possible de sécuriser encore quelque peu la connexion? Par exemple.:

  • Créer des identifiants pour rendre les attaques répétées difficiles?
  • Crypter le mot de passe envoyé depuis un champ de mot de passe HTML?

En particulier, j'utilise CakePHP et un appel AJAX POST pour déclencher l'authentification (inclut le nom d'utilisateur et le mot de passe fournis).

Mise à jour sur le problème:

  • HTTPS n'est pas disponible. Période. Si vous n'aimez pas la situation, considérez cela comme une question théorique.
  • Il n'y a pas d'exigences explicites, vous avez tout ce que HTTP, PHP et un navigateur (cookies, JavaScript, etc.) offre dans la vie réelle (pas de binaires RSA magiques, de plugins PGP).
  • La question est, quel est le meilleur, vous pouvez faire de this situation, qui est mieux que d'envoyer les mots de passe en clair. Connaître les inconvénients de chacune de ces solutions est un avantage.
  • Toute amélioration meilleure que les mots de passe simples est la bienvenue. Nous ne visons pas une solution 100% l33tG0Dhx0r-proff. Difficile de craquer vaut mieux que de compliquer à pirater, ce qui est mieux qu’un simple reniflement révélant le mot de passe.
73
sibidiba

HTTPS est absolument vital pour maintenir une connexion sécurisée entre un site Web et un navigateur. Les réseaux wifi publics mettent les utilisateurs en danger , et lorsqu'ils sont utilisés correctement, HTTPS est le seul outil pouvant protéger les comptes d'utilisateurs cette vulnérabilité .

Si votre hôte ne prend pas en charge le protocole HTTPS, un service tel que Cloudflare Universal SSL peut être utilisé pour garantir que tous les navigateurs se connectent à votre site à l'aide de HTTPS, , même si votre serveur ne le fait pas. supporte SSL/TLS . La connexion entre Cloudflare et votre site Web ne sera toujours pas protégée, mais ce service Cloudflare est destiné à protéger les utilisateurs contre les menaces détectées sur les réseaux wifi publics. Du point de vue d'un testeur d'intrusion, ne pas fournir de protocole HTTPS est hautement suspect. Si vous ne fournissez pas une exigence de sécurité de base comme livrer du trafic, quelles sont les autres exigences de sécurité qui vous manquent? Les certificats HTTPS peuvent être obtenus gratuitement à l'aide de Let's Encrypt ou Start SSL , il n'y a aucune raison légitime de ne pas prendre en charge HTTPS.

HTTPS est essentiel car il ne se limite pas à "chiffrer les mots de passe". Un autre rôle important est d'empêcher l'utilisateur de se connecter à un serveur malveillant empruntant l'identité d'un serveur réel. L'utilisation d'un système ne protégeant que le mot de passe constitue toujours une violation de OWASP A9 - Protection insuffisante de la couche de transport car vous transmettriez toujours les informations d'identification de session en texte brut, ce qui correspond à tous les besoins de l'attaquant ( Firesheep ).

  1. la cryptographie basée sur JavaScript ne peut pas être utilisée pour construire une couche de transport sécurisé .

  2. "Tokenize logins": Si un attaquant détecte le trafic, il aura le nom d'utilisateur/mot de passe en texte brut et pourra ensuite se connecter avec ces nouvelles informations d'identification. (Replay attaque)

  3. "Crypter en quelque sorte le mot de passe transmis": une fois que la personne s'est connectée, un attaquant peut renifler le trafic pour obtenir le identifiant de session (cookie) valide, puis simplement l'utiliser au lieu de se connecter. Si l'intégralité de la session a été protégé avec SSL/TLS alors ce n’est pas un problème.

D'autres attaques plus complexes affectent à la fois ce système et notre infrastructure SSL actuelle. L'attaque SSLStrip entre dans les détails. Je recommande fortement regarder la conversation Blackhat 2009 de Moxie Marlinspike , ce qui conduit au norme HTTP-Strict-Transport-Security .

75
rook

Étant donné que vous ne pouvez pas utiliser SSL sur le serveur Web et que vous n'êtes pas un expert en sécurité, recherchez un service d'authentification sécurisé existant que vous pouvez utiliser et laissez-les gérer à la fois le SSL et la complexité de la gestion des informations d'identification pour vous. 

En particulier, je suggérerais que vous utilisiez un service d'authentification tiers gratuit, tel que OpenID . Ils ont des bibliothèques pour PHP dont une pour CakePHP .


Edit: (sur les risques)

L'utilisation d'un service d'authentification sécurisée tiers (qui utilise HTTPS lui-même) peut atténuer le problème de l'authentification sans utiliser HTTPS (sur votre serveur), mais cela n'élimine pas totalement la possibilité d'attaques.

Les deux attaques les plus courantes sont les attaques rejouées et détournement de session où l'attaquant est capable de réutiliser un jeton de session authentique plus tard, ou d'utiliser un jeton de session valide. leur propre but malveillant.

L'attaque de réexécution peut être atténuée par l'expiration du jeton de session et, de préférence, par un nonce pour empêcher la réexécution de session et réduire le risque de détournement de session. Avec un nonce, une session légitime génère une erreur en cas de piratage, car le nonce a expiré (été utilisé), de sorte que sa propre session n'est plus valide.

Si vous ne pouvez pas utiliser HTTPS pour chiffrer le jeton de session lors de la transmission vers et depuis votre serveur, vous ne pouvez pas empêcher totalement les attaques actives telles que détournement de session ou homme au centre attaque. Ceci peut être acceptable dans certains cas, tels que les sites Web avec une base d'utilisateurs réduite pour une utilisation non commerciale.

16
mctylr

La réponse courte est que sans le cryptage SSL entre points de terminaison, il est impossible de le faire en toute sécurité ...

L'une des principales raisons à cela est que vous ne pouvez pas utiliser la cryptographie sécurisée dans un navigateur. Voir cette référence - Cryptographie Javascript considérée comme nuisible .

De plus, vous ne pouvez absolument pas être sûr que la source des informations d'identification est bien à qui vous parlez. Cela signifie qu'il n'y a absolument aucun moyen, sans SSL, de s'assurer qu'il n'y a pas/ Attaque Man-Au-Milieu en cours.

Donc non, vous ne pouvez pas le faire. 

De plus, n'essayez même pas. Obtenez SSL. Vous pouvez obtenir des certificats gratuits. Les hôtes vous donneront généralement une adresse IP dédiée pour quelques $$$ par mois. Et si vous tenez vraiment à la sécurité, vous utiliserez au moins un VM avec une adresse IP dédiée. 

Même tenter cela serait Security Through Obscurity au mieux, et rien au pire. SSL est un problème résolu. Pourquoi ne pas utiliser cette solution. La sécurité n'est pas une chose à deviner. Utilisez les techniques appropriées. N'essayez pas d'inventer le vôtre. Ça ne marchera pas ...

14
ircmaxell

Comme vous l'avez suggéré, vous pourrez peut-être générer un jeton unique chaque fois que la page sera créée. Ce même jeton devra être renvoyé avec les données du formulaire et ne pourra pas être réutilisé. Vous pouvez également protéger le mot de passe en utilisant JavaScript pour le hachage, si vous pouvez vous fier à ce qu'il soit activé par vos utilisateurs. 

Ce schéma n'est toujours pas sécurisé, cependant. Un attaquant pouvait toujours voir tout ce qui se passait sur le fil. Ils pourraient intercepter le jeton et vous envoyer une réponse avant l'utilisateur. Ou bien ils pourraient simplement attendre que quelqu'un se connecte, volent les informations d'identification de cette personne (au fur et à mesure de leur envoi), et fassent leur propre demande de connexion ultérieurement.

Ligne de fond - Vous devez utiliser HTTPS pour garantir la sécurité du site.

13
Justin Ethier

Vous pouvez chiffrer le mot de passe en utilisant Javascript et le déchiffrer sur le serveur.

Je recommanderais de générer une paire de clés RSA sur le serveur, d'envoyer la clé publique avec un sel temporisé au navigateur, puis de chiffrer le mot de passe, associé au sel, à l'aide de la clé publique en Javascript.

Vous pouvez trouver une implémentation RSA en Javascript ici

Vous devez inclure à la fois l'adresse IP et l'intégralité de X-FORWARDED-FOR hedaer dans les cookies d'authentification afin d'éviter le vol de cookies par des mandataires.

Si vous utilisez des données sensibles, vous pouvez générer une clé AES aléatoire en Javascript , puis l'envoyer au serveur avec le mot de passe crypté avec RSA.
Vous pouvez ensuite demander à l’application entière d’utiliser des requêtes chiffrées AJAX à partir d’une seule page et de ne pas utiliser de cookie d’authentification du tout.

Notez qu'il n'est pas possible de se protéger contre une attaque active d'interception sans SSL. Un attaquant actif peut complètement remplacer votre site par son propre proxy, et il n’ya aucun moyen de se défendre contre cela. (Puisqu'il ne peut y avoir aucun bon code connu)

6
SLaks

Vous pouvez utiliser HTTP Digest authentication, qui est pris en charge par la plupart des navigateurs et n'envoie pas le mot de passe en clair sur le fil. 

L'inconvénient est la boîte de connexion laide affichée par Broswer. Si vous préférez vous en tenir aux formulaires, vous pouvez implémenter exactement le même protocole que HTTP Digest dans votre authentification de formulaire: envoyez des champs cachés contenant le domaine et le défi, et demandez au client d'ajouter JavaScript à la nonce et de calculer le résumé. De cette façon, vous utiliserez un protocole d’échange bien connu et éprouvé, plutôt que de vous lancer vous-même.

HTTP Digest nécessite uniquement des opérations de hachage.

6
Remus Rusanu

Qu'en est-il Authentification HTTP Digest ? Il fournit une sécurité par nom d'utilisateur MD5, un mot de passe et un mot de passe (entre autres) avant de l'envoyer au serveur. MD5 n'est pas vraiment sécurisé, mais c'est un bon moyen de sécurité simple avec HTTP.

Bien sûr, cela n'empêche pas les pirates de modifier le message ... mais cela sécurise votre mot de passe.

2
AndiDog

Connectez-vous sans HTTPS, comment sécuriser?

Puisqu'il n'y a pas de canal sécurisé entre votre serveur et votre client:

  • parce qu'il n'y a pas de canal sécurisé, tout le monde peut surveiller votre trafic.
  • comme tout le monde peut surveiller le trafic, vous êtes ouvert à une attaque MITM.
  • parce que vous êtes ouvert aux attaques MITM, il n’est pas garanti que votre client verra une page légitime.
  • parce que les pages ne sont pas légitimes et que votre page n’est en réalité pas servie (le gars du milieu desserve les pages), toutes les astuces utilisées côté serveur sont rendues inutiles.

Que pouvez-vous faire? Théoriquement?

  • le client et le serveur doivent tous deux utiliser le chiffrement pour rendre la surveillance/MITM moins susceptible.
  • suppose que vous ne pouvez pas avoir une poignée de main,
  • supposons que votre client a déjà votre clé et sait parler le même charabia que votre serveur.
  • que diriez-vous de SSL sur HTTP mais encapsulé dans un message codé en base64 pour un charabia?

Mais attendez ... Puisque vous avez dit pas de binaire magique, ni de plugin, pas même RSA, je ne sais pas si cela est possible, sauf pour le cryptage interne (parfois très faible).

-

1
dnozay

Vous pouvez essayer de le répliquer à un moment donné, en utilisant le cryptage à clé publique (GPG peut-être) et en utilisant la mise en cache du navigateur.

Ce n'est pas quelque chose de sécurisé, même mettre en place SSL ne sera pas suffisant pour un attaquant sophistiqué, vous devez utiliser HSTS, identification de clé publique, etc. pour simplement considérer un site Web sécurisé aujourd'hui.

Le reste de la réponse n'est que matière à réflexion. 

  1. Créez une paire de clés publique-privée. Gardez le privé sécurisé.
  2. Créez un fichier js contenant la clé publique et une fonction encrypt, recherchez un algorithme de cryptage sécurisé. Cette fonction devrait chiffrer une chaîne donnée (forme sérialisée) avec un horodatage supplémentaire, pour éviter une attaque de réplication.
  3. Servir ce fichier avec Cache-Control:public, max-age=31536000 en-tête HTTP. Nous essayons d'atténuer les attaques lorsque l'attaquant tente de remplacer le script. Le fichier sera toujours servi à partir du cache du navigateur. 
  4. Envoyez tous les formulaires via Javascript, en utilisant la fonction encrypt. Servez-les avec le même en-tête que ci-dessus.
  5. Sur le serveur, decrypt les données, vérifiez l'horodatage, s'il est toujours valide. Pensez-vous, sinon, jetez-le.
  6. Créez un jeton de cookie qui ne peut être utilisé qu'une seule fois pendant une très courte période. Si l'attaquant s'empare d'un cookie, il n'aura pas beaucoup de temps pour faire des choses. Toutefois, si l'attaquant est suffisamment rapide, il peut alors déconnecter l'utilisateur d'origine.
  7. Changer les cookies à chaque réponse. Mais alors que faites-vous lorsque l’utilisateur envoie plusieurs demandes en même temps et qu’elles arrivent ensuite dans l’ordre inverse? Quel cookie est valide? Cela crée des tonnes de problèmes au prix d'un faux sentiment de sécurité.

Tous les écouteurs ne pourront pas utiliser les données dans les deux sens et ne pourront pas modifier/injecter les fichiers existants JS jusqu'à l'expiration du cache/l'utilisateur efface le cache. Cependant, tout attaquant sophistiqué peut remplacer l’ensemble du fichier HTML, ce qui annulerait toutes les mesures de sécurité que je viens de mentionner. Si vous pouvez au moins servir ce fichier/formulaire sur HTTPS, vous pourriez vous en tirer, mettez-le sur des pages github ou quoi que ce soit d'autre. Cependant, si vous placez le fichier dans un autre domaine, vous devez configurer CORS pour le domaine de réception pour que cela fonctionne.

Un autre essai

Des mots de passe uniques envoyés par courrier électronique.

  1. L'utilisateur remplit son courrier électronique, clique sur un lien qui lui envoie un lien avec un jeton qui lui permettra de se connecter.
  2. L'utilisateur clique sur le lien
  3. Le serveur vérifie le jeton, connecte l'utilisateur.
  4. Rouler les cookies comme dans l'exemple précédent.

Dans l’ensemble, quoi que vous fassiez, c’est pas sûr . Face à un attaquant rapide et sophistiqué, rien ne fait obstacle.

Obtenez SSL, si l'infrastructure ne le supporte pas, changez-le. Si votre responsable ne croit pas au SSL, convainquez-le. Ne créez pas un faux sentiment de sécurité. Protégez les données de vos utilisateurs. En fonction de votre emplacement, vous êtes légalement tenu de protéger les données de vos utilisateurs.

Ensuite, parlons de la sécurisation d’un site avec SSL.

1
Umur Kontacı

Créez une paire de clés publique/privée à l'aide d'un chiffrement asymétrique.

Créez une clé symétrique sur le serveur.

Envoyez la clé publique du côté client.

Créez une clé aléatoire pour le côté client à chiffrement symétrique.

Cryptez cette clé aléatoire en utilisant le côté client de la clé publique.

Envoyez la clé cryptée au serveur.


Le serveur effectue les opérations suivantes:

une. Déchiffre la clé symétrique aléatoire à l'aide de la clé privée.

b. Crée un jeton contenant la clé de client générée.

c. Signe le jeton.

ré. Crypte le jeton à l'aide de la clé symétrique du serveur.

e. Crypte le jeton déjà chiffré avec la clé générée par le client.

f. Envoie le jeton crypté vers le bas.


Le client reçoit ce jeton et procède comme suit:

une. Déchiffre le jeton avec la clé générée.

b. Stocke le jeton déchiffré.

c. À ce stade, le jeton stocké est uniquement crypté avec la clé symétrique du serveur.


Sur chaque du client au serveur:

une. Cryptez les données sortantes à l'aide de la clé générée par le client.

b. Envoyer le jeton + données cryptées


À chaque demande que le serveur reçoit:

une. Décryptez le jeton à l'aide de la clé symétrique du serveur.

b. Vérifiez la signature.

c. Décryptez les données à l'aide de la clé générée par le client stockée dans le jeton.

0
Hedzer

Regardez "Le protocole de mot de passe distant sécurisé".

Au lieu de le formuler moi-même, laissez-moi citer un extrait de leur site Web:

Le protocole de mot de passe sécurisé à distance effectue une authentification à distance sécurisée de mots de passe courts mémorisables par l'homme et résiste aux attaques réseau passives et actives.

et:

Le protocole associe des techniques de preuves à zéro connaissance et des protocoles d’échange de clés asymétriques et offre des performances considérablement améliorées par rapport aux méthodes étendues relativement résistantes qui résistent aux attaques par vérificateurs volés telles que Augmented EKE ou B-SPEKE.

Bien que l'Université de Stanford ne fournisse pas d'implémentations pour PHP et JavaScript, elles sont liées à des implémentations tierces.

L'un de ces liens mène à "Clipperz", un gestionnaire de mot de passe en ligne. Il est également disponible en édition communautaire sur GitHub. Là, ils hébergent leur "javascript-crypto-library" , qui implémente le protocole et le "password-manager" lui-même, qui contient les backends écrits en PHP et en Python.

Je ne peux pas dire à quel point il serait difficile d'extraire les parties de code pertinentes, mais vous pouvez peut-être réutiliser leur implémentation (sous licence AGPL).

Edit 2014/10/24:

L'article de Wikipedia sur SRP répertorie quelques implémentations supplémentaires. Pertinent pour PHP/JS:

0
ben