Comprendre le vecteur d'attaque
Comment fonctionnent les HashMaps
Supposons qu'un formulaire de commentaire sur un blog accepte les paramètres - prénom, nom, commentaire - comme paramètres de poste. En interne, Tomcat stocke ces paramètres comme un HashMap.
El structure logique de ce HashMap est comme ceci -
"first_name" --> "Sripathi"
"last_name" --> "Krishnan"
"comment" ---> "DoS using poor Hashes"
Mais le structure physique est différent. Les clés sont d'abord converties en un hashCode, puis le hashCode est converti en un index de tableau.
El structure physique idéale devient donc -
0 --> "Sripathi"
1 --> "Krishnan"
2 --> "DoS using poor Hashes"
Mais les clés possibles sont infinies. Donc, à un moment donné, deux clés auront le même code de hachage. Cela devient une collision de hachage.
Avec les collisions, les structure physique devient :
0 --> "Sripathi", "Krishnan"
1 --> Empty
2 --> "DoS using poor hashes"
Collisions de hachage et impact sur les performances
En cas de collisions de hachage, l'insertion d'une nouvelle entrée implique d'itérer sur tous les éléments d'un même "seau" de hachage. séquentiellement juste pour savoir si elle existe déjà dans la carte. L'insertion d'un élément peut approcher la complexité O(n) si tous les éléments sont hachés à la même valeur. L'insertion de n éléments dans ce pire cas rend la complexité O(n*n).
En bref : Si vous insérer des milliers de clés qui ont le même hashCode le serveur aura besoin de beaucoup de cycles CPU.
Comment générer des clés avec le même Hash ?
En Java, "Aa" et "BB" ont le même code de hachage.
Grâce à une propriété appelée "Sous-chaînes équivalentes", nous pouvons générer plusieurs autres chaînes avec le même code de hachage, en commençant simplement par ces deux chaînes.
Première itération : "AAAA", "AABb", "BbAA", "BbBb" ont le même code de hachage.
Maintenant, nous avons 4 chaînes de caractères avec le même code de hachage. Nous pouvons les permuter pour générer 16 chaînes de caractères qui auront le même code de hachage. Par exemple :
"AaAaAaAa", "AaAaBBBB", "AaAaAaBB", "AaAaBBAa",
"BBBBAaAa", "BBBBBBBB", "BBBBAaBB", "BBBBBBAa",
"AaBBAaAa", "AaBBBBBB", "AaBBAaBB", "AaBBBBAa",
"BBAaAaAa", "BBAaBBBB", "BBAaAaBB", "BBAaBBAa",
Ces 16 chaînes de caractères ont toutes le même code de hachage.
Vous pouvez maintenant prendre ces 16 chaînes et générer 256 chaînes qui ont le même code de hachage.
En bref : il est très facile de générer un grand ensemble de chaînes de caractères qui auront le même code de hachage.
Comment attaquer le serveur ?
- Créez des milliers de chaînes de caractères ayant le même code de hachage (voir ci-dessus).
- Construisez une requête POST comme ceci - AaAa=&AaBB=&BBAa=&BBBB= ....
- Soumettre le formulaire
- Répétez l'opération en boucle, et créez plusieurs threads pour que toutes les ressources du serveur soient utilisées.
Comme il s'agit simplement d'une demande POST, un attaquant peut également utiliser des navigateurs innocents pour attaquer un serveur. Il suffit de trouver un site Web présentant une vulnérabilité de type "cross site scripting", d'intégrer un code pour effectuer une requête POST, puis d'utiliser l'ingénierie sociale pour diffuser le lien à autant d'utilisateurs que possible.
Prévention
En général, la plate-forme sous-jacente ne peut pas résoudre ce problème. On considère qu'il s'agit d'un problème de cadre d'application. En d'autres termes, c'est Tomcat qui doit résoudre ce problème, et non Oracle/Sun.
Les corrections possibles comprennent :
-
Limiter le nombre de paramètres POST - Tomcat 6.0.35+ a un nouveau paramètre maxParameterCount . La valeur par défaut est de 10 000. Plus elle est faible, mieux c'est, tant qu'elle ne casse pas votre fonctionnalité.
-
Limiter la taille de la requête POST - Pour que l'attaque fonctionne, la charge utile doit être énorme. Le POST par défaut autorisé par Tomcat est de 2MB. Réduire cela à disons 200KB réduira l'efficacité de cette attaque. Le paramètre dans Tomcat est maxPostSize
-
Pare-feu pour applications Web - Si vous disposez d'un pare-feu d'application Web, vous pouvez le configurer pour qu'il bloque les demandes qui semblent suspectes. Il s'agit d'une mesure réactive, mais elle est utile au cas où vous ne pourriez pas utiliser l'une des solutions ci-dessus.
FYI - La documentation de Tomcat est ici - http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
1 votes
J'ai lu quelque part que Tomcat a publié un correctif pour ce problème. Le moyen le plus rapide et le plus sûr est de faire une mise à jour.
1 votes
Pour être sûr, je corrigerais moi-même HashMap hash ou String hashCode, à moins que Tomcat n'ait un correctif que vous pouvez utiliser.
0 votes
Il pourrait y avoir de nombreuses autres applications qui dépendent de l'implémentation de référence, à moins qu'ils ne mettent en place leur propre implémentation des structures de données de hachage, par exemple, comme Peter l'a suggéré. Je me demande pourquoi le R.I. ne fournit pas directement une solution à ce problème.
1 votes
Suggérer la migration vers Serverfault ou Security.SE.
2 votes
Bien que cela s'applique bien sûr à Java (et à un certain nombre d'autres langages) en général, il convient de noter que Tomcat a déjà des correctifs dans le tronc pour les branches 6 et 7. Voir markmail.org/message/
2 votes
Il est bon de savoir que dans Java SE 7, il existe un mode de hachage alternatif disponible dans le JRE qui protège contre ce problème, bien qu'il soit désactivé par défaut pour des raisons de rétrocompatibilité. Dans Java 8, ce problème a été abordé de manière plus complète par la JEP-180 ( openjdk.java.net/jeps/180 )