J'ai une API où le visiteur peut envoyer un e-mail par abonnement:
/ api/abonnez-vous
Pour éviter une charge massive due à l'exposition du public, comment puis-je sécuriser ce point de terminaison? Dois-je utiliser la base de données ou puis-je m'en passer avec une sorte de mise en cache, de mémoire, etc. qui libère 10 minutes, etc.?
J'ai fini d'utiliser WebApiThrottle que vous pouvez utiliser pour limiter le montant de la demande sur le point de terminaison sélectionné.
Vous pouvez utiliser Proof of Work pour appliquer la limitation de débit sans avoir à mémoriser les adresses IP.
Avec la preuve de travail, vous exigez que le client effectue une fonction coûteuse en termes de calcul pour générer une preuve que vous pouvez vérifier à moindre coût. L'un des PoW les plus courants est l'inversion de hachage partielle, dans laquelle vous exigez que chaque soumission d'API soit attachée avec un hachage de preuve + demande, pour lequel le hachage doit avoir un préfixe prédéfini (généralement des zéros) d'une certaine longueur. Pour le client, le calcul de la preuve nécessite de tester des centaines ou des milliers de preuves potentielles, jusqu'à ce qu'elles tombent sur une qui possède le nombre de zéros requis; l'objectif devrait être d'exiger des clients types qu'ils dépensent plusieurs secondes ou minutes de puissance de calcul pour chaque message envoyé. Mais pour le serveur, la vérification de la preuve implique un seul calcul de hachage. Cette asymétrie signifie qu'il est beaucoup plus coûteux pour le client de générer une demande valide que pour le serveur de rejeter des demandes non valides.
Pour empêcher une attaque de relecture, vous pouvez exiger que les demandes contiennent un horodatage ou un compteur. Votre serveur peut vérifier pour rejeter les demandes contenant des horodatages trop anciens ou contenant une valeur de compteur déjà utilisée.
J'ai fait cela, donc je sais comment cela se fait de manière optimale. L'idée est d'utiliser une fonction de hachage telle que SipHash pour calculer une valeur de hachage pour l'adresse IP. Ensuite, vous utilisez un algorithme compartiment de jetons pour chaque compartiment de hachage: ayez par exemple 100 jetons initiaux dans chaque compartiment de hachage, ajoutez 10 jetons par seconde jusqu'à un maximum de 100 jetons et supprimez un jeton à chaque fois que vous recevez une demande, ou s'il n'y a pas de jetons, rejetez la demande. Cela permettrait 10 requêtes par seconde avec une taille de rafale maximale de 100.
Théoriquement, il est possible que deux adresses IP soient hachées dans le même compartiment, mais ce n'est pas un problème dans ce cas d'utilisation, si vous avez suffisamment de compartiments de hachage.
Quant à la mise à jour des compartiments, vous pouvez les faire à l'aide de minuteries par lots. Par exemple. pour les godets 131072, vous pouvez mettre à jour par ex. 4096 seaux par minuterie, puis 32 minuteries expirent uniformément en une seconde. Ainsi, à 1/32 seconde, vous mettez à jour les premiers 4096 compartiments, à 2/32 secondes, vous mettez à jour les prochains 4096 compartiments, etc. La structure de données pour la maintenance des temporisateurs est de manière optimale un file d'attente prioritaire comme un tas binaire .
Lorsqu'il est implémenté de cette façon, si quelqu'un inonde votre système de nombreuses adresses IP source falsifiées, votre mémoire n'est pas remplie.
La mémoire utilisée par cette approche utilise 8, 16 ou 32 bits par chaque compartiment de hachage si vous utilisez un tableau d'entiers. La taille entière provient de vos besoins: par ex. 8 bits ne peuvent pas prendre en charge plus de 255 tailles de rafale. De même, 16 bits autorisent des tailles de rafale d'au plus 65 535. Ainsi, par ex. 8 bits ou 1 octet par compartiment et 131072 compartiments prennent 128 kilo-octets de mémoire. Nulle part près d'être un problème. Une bonne machine a au moins 2 Go de mémoire, ce qui signifie plus de 15 000 fois la quantité dont vous avez besoin pour ce système.
Vous devez également prendre en compte la bande passante mémoire: si chaque compartiment est mis à jour une fois par seconde, la bande passante requise est de 128 Ko/s. De bons ordinateurs prennent en charge plus de 5 Go/s de bande passante en lecture/écriture, soit plus de 40 000 fois ce que ma proposition utilise.
Enregistrez le cache dans la RAM. N'utilisez pas de base de données ou de fichier disque pour cela. Si votre système tombe en panne, eh bien, il vous suffit d'initialiser tous les compartiments à la valeur initiale.
Par exposition publique , vous voulez dire que l'API elle-même ne nécessite aucune authentification? Vous pouvez reconsidérer le choix de le rendre public en premier lieu. Tout ce qui vous coûte des ressources et pourrait en outre vous causer des ennuis (envoyer trop d'e-mails vous causerait des ennuis avec les filtres anti-spam et les personnes qui les reçoivent e-mails) ne doivent pas être accessibles au public, mais limités aux utilisateurs enregistrés que vous pouvez interdire (ou, mieux, faire chaque demande payée).
Si, pour une raison quelconque, vous ne pouvez pas exiger d'authentification, vous ne pouvez malheureusement pas faire grand-chose. Vous pouvez rechercher des attaques DOS et DDOS; vous trouverez beaucoup de ressources, mais aucune ne vous assurera avec certitude que l'API serait utilisée par des personnes sages à des fins légitimes uniquement.
Quant au blocage par IP, c'est la protection la plus basique, la moins efficace et aussi la plus problématique contre DOS et DDOS. Ses principaux problèmes sont:
Le fait que la même adresse IP puisse être utilisée par plusieurs personnes. Dans l'entreprise dans laquelle je travaille, nous sommes probablement plusieurs milliers à partager la même adresse IP publique (ou une petite plage d'adresses IP).
Cela a provoqué quelques problèmes avec certains sites Web, y compris Stack Exchange, qui a affirmé à plusieurs reprises qu'il avait reçu trop de demandes de l'adresse IP et nous a bloqués. Eh bien, en effet, des centaines de développeurs travaillant en même temps génèrent beaucoup de demandes.
Dans une entreprise précédente, c'est Google Search qui nous bloquait parfois, obligeant à remplir un CAPTCHA. Ici aussi, des centaines de personnes travaillant en même temps peuvent effectuer de nombreuses recherches Google chaque minute.
Le fait qu'une attaque DDOS soit spécifiquement effectuée à partir de plusieurs adresses IP. Vous pouvez recevoir des centaines ou des milliers de demandes provenant chacune d'une adresse IP différente, toutes arrivant sur vos serveurs en même temps. Et même si vous essayez de bloquer ces adresses (qui peuvent appartenir à des personnes qui n'avaient aucune intention ni compétence pour nuire à votre serveur et qui ne savent même pas que votre site Web existe), l'attaquant peut basculer relativement facilement vers d'autres machines.