Ce que fait vraiment l'attaque
Il y a un détail subtil mais intelligent à propos de cette attaque que d'autres répondeurs ont manqué. Notez le message d'erreur Duplicate entry ':sjw:1:ukt:1' for key 'group_key'
. La chaîne :sjw:1:ukt:1
est en fait le résultat d'une expression évaluée par votre serveur MySQL. Si votre application renvoie la chaîne d'erreur MySQL au navigateur, le message d'erreur peut entraîner une fuite de données de votre base de données.
Ce type d'attaque est utilisé dans les cas où le résultat de la requête n'est pas autrement renvoyé au navigateur (injection SQL aveugle), ou lorsqu'une attaque UNION SELECT classique est compliquée à réaliser. Cela fonctionne également dans les requêtes INSERT/UPDATE/DELETE.
Comme le note Hawili, la requête particulière d'origine n'était pas censée divulguer des informations, c'était juste un test pour voir si votre application est vulnérable à ce type d'injection.
L'attaque n'a pas échouer comme suggéré par MvG, provoquer cette erreur est le but de la requête.
Un meilleur exemple de la façon dont cela peut être utilisé :
> SELECT COUNT(*),CONCAT((SELECT CONCAT(user,password) FROM mysql.user LIMIT 1),
> 0x20, FLOOR(RAND(0)*2)) x
> FROM information_schema.tables GROUP BY x;
ERROR 1062 (23000): Duplicate entry 'root*309B17546BD34849D627A4DE183D3E35CD939E68 1' for key 'group_key'
Pourquoi l'erreur est générée
Pourquoi la requête provoque cette erreur dans MySQL est un peu un mystère pour moi. Cela ressemble à un bogue MySQL, puisque GROUP BY est censé traiter les entrées en double en les agrégeant. En fait, la simplification de la requête par Hawili ne cause pas l'erreur !
L'expression FLOOR(RAND(0)*2)
donne les résultats suivants dans l'ordre, sur la base de l'argument de départ aléatoire 0 :
> SELECT FLOOR(RAND(0)*2)x FROM information_schema.tables;
+---+
| x |
+---+
| 0 |
| 1 |
| 1 | <-- error happens here
| 0 |
| 1 |
| 1 |
...
Étant donné que la 3e valeur est un doublon de la 2e, cette erreur est renvoyée. Toute table FROM avec au moins 3 lignes peut être utilisée, mais information_schema.tables est une table commune. Les parties COUNT(*) et GROUP BY sont nécessaires pour provoquer l'erreur dans MySQL :
> SELECT COUNT(*),FLOOR(RAND(0)*2)x FROM information_schema.tables GROUP BY x;
ERROR 1062 (23000): Duplicate entry '1' for key 'group_key'
Cette erreur ne se produit pas dans la requête équivalente à PostgreSQL :
# SELECT SETSEED(0);
# SELECT COUNT(*),FLOOR(RANDOM()*2)x FROM information_schema.tables GROUP BY x;
count | x
-------+---
83 | 0
90 | 1
(Désolé d'avoir répondu avec 1 an de retard, mais je suis tombé dessus aujourd'hui. Cette question m'intéresse car je ne savais pas qu'il existait des moyens de divulguer des données via des messages d'erreur de MySQL)