security prevent cheat - Comment fonctionne l'injection SQL de la BD XKCD "Bobby Tables"?





6 Answers

Disons que le nom a été utilisé dans une variable, $Name . Vous exécutez ensuite cette requête:

INSERT INTO Students VALUES ( '$Name' )

Ce que vous obtenez est:

INSERT INTO Students VALUES ( 'Robert' );  DROP TABLE STUDENTS; --' )

Le -- seulement les commentaires le reste de la ligne.

sheet php java

Juste en regardant:

(Source: https://xkcd.com/327/ )

Que fait ce SQL:

Robert'); DROP TABLE STUDENTS; --

Je sais que les deux sont des commentaires, mais le mot DROP n'est-il pas aussi commenté puisqu'il fait partie de la même ligne?




Non, ' n'est pas un commentaire en SQL, mais un délimiteur.

Maman a supposé que le programmeur de base de données a fait une demande ressemblant à:

INSERT INTO 'students' ('first_name', 'last_name') VALUES ('$firstName', '$lastName');

(par exemple) pour ajouter le nouvel étudiant, où le contenu de la variable $xxx été extrait directement d'un formulaire HTML, sans vérifier le format ni échapper les caractères spéciaux.

Donc, si $firstName contient Robert'); DROP TABLE students; -- Robert'); DROP TABLE students; -- Robert'); DROP TABLE students; -- le programme de base de données exécutera la requête suivante directement sur la base de données:

INSERT INTO 'students' ('first_name', 'last_name') VALUES ('Robert'); DROP TABLE students; --', 'XKCD');

c'est à dire. il terminera tôt l'instruction d'insertion, exécutera tout code malveillant que le pirate veut, puis commentera tout reste de code qu'il pourrait y avoir.

Mmm, je suis trop lent, je vois déjà 8 réponses avant les miennes dans le groupe orange ... :-) Un sujet populaire, semble-t-il.




Dites que vous avez naïvement écrit une méthode de création d'étudiant comme ceci:

void createStudent(String name) {
    database.execute("INSERT INTO students (name) VALUES ('" + name + "')");
}

Et quelqu'un entre le nom Robert'); DROP TABLE STUDENTS; -- Robert'); DROP TABLE STUDENTS; --

Ce qui est exécuté sur la base de données est cette requête:

INSERT INTO students (name) VALUES ('Robert'); DROP TABLE STUDENTS --')

Le point-virgule termine la commande d'insertion et en démarre une autre; le - commente le reste de la ligne. La commande DROP TABLE est exécutée ...

C'est pourquoi les paramètres de liaison sont une bonne chose.




Le '); termine la requête, il ne démarre pas un commentaire. Ensuite, il supprime la table des étudiants et commente le reste de la requête qui devait être exécutée.




Dans ce cas, 'n'est pas un caractère de commentaire. Il est utilisé pour délimiter les littéraux de chaîne. Le dessinateur de bande dessinée mise sur l'idée que l'école en question a un SQL dynamique quelque part qui ressemble à ceci:

$sql = "INSERT INTO `Students` (FirstName, LastName) VALUES ('" . $fname . "', '" . $lname . "')";

Alors maintenant le caractère 'termine le littéral de chaîne avant que le programmeur ne l'attende. Combiné avec le; caractère pour mettre fin à la déclaration, un attaquant peut maintenant ajouter tout ce qu'il veut. Le - commentaire à la fin est de s'assurer que tout sql restant dans l'instruction d'origine n'empêche pas la requête de compiler sur le serveur.

FWIW, je pense aussi que la bande dessinée en question comporte un détail important: si vous songez à désinfecter les entrées de votre base de données, comme le suggère la bande dessinée, vous vous trompez encore. Au lieu de cela, vous devriez penser en termes de mise en quarantaine de vos entrées de base de données, et la manière correcte de le faire est via des requêtes paramétrées.




Voici comment cela fonctionne: Supposons que l'administrateur recherche des enregistrements d'étudiant

Robert'); DROP TABLE STUDENTS; --

Étant donné que le compte d'administrateur a des privilèges élevés, la suppression de la table de ce compte est possible.

Le code pour récupérer le nom d'utilisateur de la requête est

Maintenant, la requête serait quelque chose comme ceci (pour rechercher la table des étudiants)

String query="Select * from student where username='"+student_name+"'";

statement.executeQuery(query); //Rest of the code follows

La requête résultante devient

Select * from student where username='Robert'); DROP TABLE STUDENTS; --

Puisque l'entrée de l'utilisateur n'est pas hygiénique, la requête ci-dessus est manipulée en 2 parties

Select * from student where username='Robert'); 

DROP TABLE STUDENTS; --

Le double tiret (-) commentera simplement la partie restante de la requête.

Ceci est dangereux car il peut annuler l'authentification par mot de passe, le cas échéant

Le premier fera la recherche normale.

Le second laissera tomber l'étudiant de table si le compte a des privilèges suffisants (Généralement le compte d'admin d'école exécutera une telle question et aura les privilèges mentionnés ci-dessus).




Related