J'ai réfléchi à Bcrypt récemment et ce que je me demande, c'est s'il y a un moyen de traiter les problèmes inhérents (d) DOS avec des fonctions de hachage lente. À savoir, si je configurais BCRYPT, ma machine prend 100 ms vers un mot de passe hachage, elle ne prend que 10 tentatives de mot de passe par seconde pour rendre mon serveur insuffisant. Je pourrais réduire la difficulté, mais plus je le fais plus vite pour moi, plus je le fais plus vite pour un attaquant. Je pourrais interdire toute personne qui essaie trop de mots de passe, mais les botnets sont partout ces jours-ci.
Y a-t-il des solutions communes à ce problème?
Je pensais qu'il y avait probablement des stratégies où vous rendez le client quelque chose de compliqué mais facilement vérifiable et de vérifier le résultat avant de vérifier le mot de passe, mais il a quelques problèmes:
Une autre chose que j'avais envisagée était la mise en cache BCRYPT Résultats en mémoire, de sorte que les attaques contre un utilisateur ne causent pas de problèmes, mais que si j'ai trop d'utilisateurs à faire raisonnablement cela?
Je pense principalement à l'utiliser dans le contexte d'une boîte de connexion Nom d'utilisateur/mot de passe sur un site Web, mais toute méthode de traitement de cela pourrait être faite dans JavaScript s'il n'y a rien de mieux.
ÉDITER:
L'idée de la limitation de taux d'une manière ou d'une autre est utile, mais ce n'est pas le genre de solution que j'avais à l'esprit. Il fabrique des attaques DDOS plus chères (car vous avez besoin de plus d'adresses IP), mais cela ne résout pas le problème fondamental que le serveur fait de manière significative plus de travail que l'attaquant (s).
Un exemple de ce que je pense, c'est comment utiliser un mot de passe salé fait des tables arc-en-ciel pire qu'une attaque directe de force brute. Donc, si vous utilisez du sel, vous n'avez pas à vous soucier des tables arc-en-ciel, car il y a de meilleures attaques. Ce que je veux, c'est un moyen de faire attaquer ma page de connexion non mieux (ou pire) que de frapper des URL aléatoires.
Une possibilité est d'envisager d'utiliser puzzles client . L'idée de base est de forcer le client à effectuer une quantité importante de travail et de prouver qu'elle l'a fait, avant d'accepter une paire de nom d'utilisateur/mot de passe et essayez de le valider.
Voici un aperçu de l'approche. Le serveur génère un puzzle aléatoire et envoie le puzzle au client. Le serveur génère le puzzle de manière à ce qu'il puisse prédire raisonnablement combien d'effort sera nécessaire pour résoudre le puzzle (par exemple, 100 ms de calcul). Le client résout le puzzle, puis envoie la solution avec le nom d'utilisateur et le mot de passe de l'utilisateur.
Dans un paramètre Web, cela serait probablement mis en œuvre avec JavaScript: la page de connexion contiendrait le code JavaScript pour résoudre le puzzle et la description du puzzle. Un navigateur Web de l'utilisateur légitime exécuterait le JavaScript sur la page, qui résoudrait le puzzle et inclure la solution sous la forme avec le nom d'utilisateur et le mot de passe.
Cela rend plus difficile pour un attaquant de DOS le serveur. Par exemple, si cela prend le serveur 100 ms de calcul pour vérifier la validité du mot de passe de l'utilisateur, et si le serveur choisit un puzzle qui prend 100 ms à résoudre, un attaquant devra faire au moins autant de travail que le serveur. Si vous allumez la molette pour sélectionner des énigmes qui prendront à 200 ms pour résoudre, alors l'attaquant doit faire deux fois plus de travail que vous, pour vous. Cela n'empêche donc pas DOS, mais cela rend plus difficile et nécessite que l'attaquant investit plus de ressources - ce qui peut réduire quelque peu le risque.
Voici un exemple très simple de la construction d'un puzzle. La description du puzzle est un nombre aléatoire sur 128 bits [~ # ~] r [~ # ~] (choisi par le serveur, et envoyé au client). L'objectif est de trouver un certain nombre n tel que SHA256 ( [~ # ~] r [~ # ~], n ) est nul dans ses bas 20 bits. Le client boucle de boîte sur les valeurs de n (test si n = 0 est une solution, tester si n = 1 est une solution, tester si n = 2 est une solution, ...) jusqu'à ce que le client trouve une solution. En moyenne, vous devriez vous attendre à ce que cela prenne environ 220 essais. Si le client peut effectuer environ dix millions de hachages par seconde, alors 220 Les essais devraient prendre environ un dixième de seconde (100 ms). Une fois que le client trouve une solution, le client peut envoyer n au serveur. Notez que le serveur peut vérifier rapidement que n est une solution valable au puzzle (il suffit d'un hachage, pas un million hash). Cela crée l'assayerie requise, où le serveur peut générer très rapidement de nouvelles puzzles et vérifier des solutions de puzzle revendiquées, mais où il faut plus de temps pour résoudre le puzzle, et où le serveur peut contrôler la durée de résolution du puzzle avec un certain degré de précision. Ce n'est qu'un exemple de construction de casse-tête; Il y a eu beaucoup de recherches sur ce problème et il y a mieuxconstructions .
Vous pourriez être particulièrement intéressé par kapow , qui implémente cette idée pour le contexte Web.
La principale limitation est que cela ne sera pas sécurisé contre une attaque dédiée. Un attaquant sérieux peut simplement acquérir un botnet de quelques centaines de machines (ce n'est pas si cher) et à votre dons, et maintenant vous êtes complètement hosté. Les puzzles des clients ne peuvent pas arrêter ce genre d'attaque: ils ne peuvent arrêter qu'une attaque relativement basse. Cependant, l'arrêt des DOS est en général très difficile.
Une limitation secondaire concerne la variabilité large de la puissance de calcul des clients pouvant accéder à votre site Web. Un puzzle qu'un bureau haut de gamme peut résoudre en 100 ms peut prendre un appareil mobile de 1 000 ms à résoudre (je propose des chiffres ici). Si vous choisissez des paramètres qui rendent le puzzle relativement facile à résoudre sur le périphérique le plus bas qui ailli l'accès à votre site Web, vous constaterez peut-être que la sécurité contre les ordinateurs de bureau haut de gamme est dégradée. En outre, il semble plausible qu'un programme C (géré par un attaquant) puisse résoudre le puzzle beaucoup plus rapidement que le JavaScript (géré par des utilisateurs légitimes), ce qui exacerberait davantage l'écart entre la rapidité avec laquelle un attaquant peut résoudre des puzzles vs. Quelle vitesse le client légitime le plus lent puisse les résoudre. Cet espace dégrade la sécurité.
Une limitation tertiaire est que les puzzles du client exigent que le client utilise JavaScript, pour vous connecter. Cependant, cela pourrait être acceptable.
Une variante de cette idée est que le serveur se surveille et vérifie si la charge est subordonnée. Dans des conditions normales, sautez le puzzle. Toutefois, si le serveur semble être sous Attack DOS, alors commencez à demander des tentatives de connexion à venir avec une solution de puzzle. Cela atténue certains des inconvénients de l'approche du puzzle client, mais est toujours loin d'être parfait et ne peut toujours pas résister à une attaque sérieuse DOS.
Je décris cette solution potentielle, au cas où vous vous intéresserez, mais je ne le recommande pas vraiment pour la plupart des sites. Pour la plupart des sites, le risque de DOS est relativement faible, et si cela se produit, vous pouvez y faire face à l'époque. Pour cette raison, je suppose que cela ne vaut probablement pas votre temps ni votre énergie pour mettre en œuvre ce type de défense. Si vous avez beaucoup de temps supplémentaire et d'énergie à épargner, vous risquez peut-être mieux de dépenser de nouvelles fonctionnalités ou de rendre votre site mieux.
La réduction du nombre de suppositions par minute est la voie à suivre, mais la mise en œuvre en tant que sleep
dans votre code consumera toujours des ressources précieuses et conduira à un déni de service.
Au lieu de cela, vous voulez que le client attend, pas le serveur. Donc, connectez-vous le temps que la tentative a été faite, ajoutez X
secondes à ce moment-là et n'essayez pas d'authentifications supplémentaires à partir de cet utilisateur/IP jusqu'à ce que cette heure a expiré. (-Modifier, ajouté :) C'est-à-dire si une tentative d'authentification est reçue, rejeter-la avec un message d'erreur sans même vérifier le mot de passe.
Vous voudrez mettre un point javascript correspondant dans la page de connexion afin que l'utilisateur ne soumettrait pas une nouvelle tentative de connexion tant que le délai d'attente ait expiré (plus une marge de sécurité). Qui empêche les utilisateurs de voir des messages d'erreur inutiles et de se confondre.
L'augmentation du délai d'attente à chaque tentative est également une bonne idée. Cela aide à empêcher de déranger les utilisateurs "normaux", tout en faisant une attaque de force brute pratiquement impossible.
Une autre approche que vous pourriez envisager est d'utiliser CAPTCHAS pour rendre ce type d'attaque DOS plus difficile. L'idée de base est d'obliger l'utilisateur à résoudre un CAPTCHA lorsqu'il souhaite vous connecter et les obliger à présenter une solution correcte au CAPTCHA avant de valider leur mot de passe.
Ceci est hostile aux utilisateurs, donc si vous souhaitez considérer cela, je recommanderais une variante. Demandez à votre serveur moniteur de sa propre charge, de sorte qu'il peut détecter quand il est attaqué. (Par exemple, mesurez la quantité de votre temps de processeur que vous dépensez sur les mots de passe de hachage BCRYPT-hachage; ou mesurez simplement la charge sur le serveur.) Dans des conditions normales, ne faites rien de spécial: les utilisateurs doivent simplement présenter un nom d'utilisateur et un mot de passe, comme d'habitude , sans captcha nulle part.
Lorsque vous détectez, vous pouvez être attaqué, entrez le mode auto-protection. Dans ce mode, le serveur doit envoyer un CAPTCHA dans la page de connexion, demandant aux utilisateurs d'entrer dans leur nom d'utilisateur, entrez leur mot de passe et entrez la solution au CAPTCHA. Lorsque l'utilisateur clique sur Soumettre, le serveur doit d'abord valider la solution au CAPTCHA avant d'utiliser BCRYPT pour vérifier le mot de passe de l'utilisateur. Si l'utilisateur n'a pas résolu correctement le CAPTCHA, n'essayez même pas de vérifier leur mot de passe.
Cela soulève la barre contre les attaques DOS, car un attaquant peut désormais envoyer 10 paires de nom d'utilisateur/mot de passe non valides par seconde: l'attaquant devra également résoudre 10 captchas par seconde au serveur DOS. En conséquence, l'attaque de DOS triviale ne réussit plus. En outre, cela fournit une résistance à DOS, tout en veillant à ce que, dans la plupart des situations, les utilisateurs n'ont jamais besoin de voir un CAPTCHA: les utilisateurs n'ont besoin que de résoudre les CAPTCHAS lorsque le serveur est attaqué.
Bien sûr, vous pouvez combiner ce schéma avec la limitation de taux par adresse IP et par nom d'utilisateur, si vous le souhaitez.
Cela dit, la sécurité de ce schéma est loin d'être parfaite. Il existe des marchés souterrains utilisés par les attaquants qui existent pour automatiser le processus de résolution de captchas pour vous, moyennant des frais. Ces services fournissent une API que leurs clients peuvent utiliser pour soumettre un CAPTCHA et récupérer la solution. Le taux d'existence est quelque chose comme quelques dollars pour mille captchas résolus. Sur la base de cela, nous pouvons calculer ce qu'il en coûterait de monter une attaque de DOS réussie contre ce schéma, en utilisant ces services de résolution de captcha. Un attaquant aurait besoin de résoudre 864 000 captchas par jour (10 par seconde) pour supprimer votre serveur, ce qui coûterait quelques milliers de dollars par jour de temps d'arrêt en utilisant des marchés existants. Ceci est une limite supérieure sur le coût de la montage d'une attaque DOS réussie. Toutefois, il estimait presque certainement le coût de la pose de votre serveur, car il y aura presque certainement d'autres moyens plus économiques de monter une attaque DOS sur votre serveur.
Quoi qu'il en soit, je partage cette solution potentielle basée sur l'utilisation de captchas, mais je ne le recommande pas vraiment pour la plupart des sites. Pour la plupart des sites, le risque de DOS est relativement faible, et si cela se produit, vous pouvez y faire face à l'époque. Pour cette raison, je suppose que cela ne vaut probablement pas votre temps ni votre énergie pour mettre en œuvre ce type de défense. Si vous avez beaucoup de temps supplémentaire et d'énergie à épargner, vous risquez peut-être mieux de dépenser de nouvelles fonctionnalités ou de rendre votre site mieux.
Actuellement, DDO est le moyen le plus simple et le moins cher de prendre votre serveur. J'ai vu des estimations pour le coût de l'attaque DDO dans la gamme de 100 $ par jour , bien qu'elle puisse coûter de manière significative plus Pour vaincre une cible plus grande et meilleure ressources.
Protéger votre serveur contre DOS Attack est pas facile ; L'économie de cela ne fonctionne pas en votre faveur. Peut-être que l'une des meilleures choses que vous puissiez faire est d'organiser votre site d'avoir beaucoup de capacité excédentaire et de s'assurer qu'elle peut accabler la circulation de la circulation (peut-être utiliser un service de cloud avec VMS et la capacité de réseau à la demande). L'avantage de cette approche est qu'il est bénéfique même si vous ne venez jamais d'attaquer DOS, car cela vous aidera à éviter d'être submergé par une inondation d'utilisateurs légitimes - par exemple, si vous êtes slashdoted.
Ce que vous pouviez faire est de forcer la demande à dormir pendant une période exponentielle sur chaque connexion échouée.
Pour la première connexion, maintenez une seconde; deuxième échec 2 secondes; Troisièmement, il a échoué 4 secondes, etc. ou plus long ou plus court en fonction de ce que votre serveur peut gérer. Cela ne fait pas de mal aux utilisateurs normaux qui enracinent leur mot de passe, mais il fait que quiconque tenter une force brute attend une très longue période après seulement quelques échecs.
Mon point de vue général sur DOS est: tous les systèmes existants sont fondamentalement vulnérables à DOS. C'est juste une question de diplôme. Si vous avez un site de haut niveau qui est à haut risque pour DOS, il peut être intéressant de vous inquiéter de ces vecteurs. Si vous venez de courir un site quotidien ordinaire, je ne me dérangerais pas. Dans la plupart des secteurs, les attaques de DOS sont rares, elles ne valent probablement pas la peine de dépenser du temps et de l'énergie à défendre. (Il y a bien sûr des exceptions, mais je parle de la plupart des sites ici.)
La grande chose à propos de DOS Attacks est que, s'ils se produisent, ils sont facilement détectables.
Modifier (2/25): On dirait que vous voulez vraiment faire ce que vous pouvez contre les attaques de DOS de calcul, malgré les limitations que j'ai articulées. Étant donné que, s'il vous plaît voir mon AutreRéponses Pour que certaines façons de rendre les attaques de DOS calculantes plus difficiles. Ils sont loin d'être parfaits et personnellement, je colle avec mes recommandations de fin de ligne (à savoir: La mise en œuvre de ces défenses n'est probablement pas la meilleure utilisation de votre temps), mais là-bas, au cas où vous vous sentirez différemment.
Ma simple recommandation, et ce que j'ai fait pour atténuer les attaques DOS sur le hachage de mot de passe ralentit, est d'utiliser un score de calcul de force de mot de passe comme méthode de validation principale.
Donc, pour un exemple de connexion utilisateur: je reçois l'enregistrement d'utilisateur par courrier électronique. Ensuite, vérifiez s'il vous plaît si le score de force correspondait au mot de passe texte clair (qui est évidemment rapide, juste quelques fonctions). Et ne démarrez que les fonctions de hachage de mot de passe avec une correspondance de partition, sinon cautionnement avec une demande échouée.
Et pour éviter d'exposer la force du mot de passe dans la base de données, vous pouvez trouver une sorte d'algorithme de calcul de base d'un moyen de masquer le score de force de mot de passe réel.