L'idée est très simple - la requête et les données sont envoyées au serveur SQL server séparément.
C'est tout.
La racine du problème de l'injection SQL est un mélange de la code et les données.
En fait, notre requête SQL est un complet programme légitime.
Et nous sommes la création de ce programme de manière dynamique par l'ajout de données à la volée. Ainsi, ces données peuvent interférer avec le programme code et même de le modifier, comme chaque injection exemple le montre:
$expected_data = 1;
$query = "SELECT * FROM users where id=$expected_data";
va produire régulièrement une requête
SELECT * FROM users where id=1
alors que ce code
$spoiled_data = "1; DROP TABLE users;"
$query = "SELECT * FROM users where id=$spoiled_data";
produira malveillants séquence
SELECT * FROM users where id=1; DROP TABLE users;
Cela fonctionne parce que nous sommes en ajoutant directement les données dans le programme de corps et de devenir une partie du programme.
Ainsi, les données peuvent modifier le programme et en fonction des données passées, nous ont un flux régulier de la production ou de la table, users
supprimé.
Alors que dans le cas de déclarations préparées à l'avance, nous ne modifions pas notre programme, il reste intact
C'est le point.
Nous envoyons le programme pour le premier serveur
$db->prepare("SELECT * FROM users where id=?");
où les données sont remplacés par des variable appelée "espace réservé".
Notez que la même requête envoyée au serveur, sans aucune des données qu'il contient! Et puis nous allons envoyer les données à la deuxième demande, totalement séparé de la requête elle-même:
$db->execute($data);
donc, il ne peut pas modifier notre programme et de faire du mal.
Assez simple, n'est-ce pas?
Cependant, il vaut la peine de noter que pas chaque fois que vous utilisez l'espace réservé, elle est traitée comme une déclaration préparée.
Espace réservé est une idée générale pour la substitution de données réelles à une variable pour l'avenir de la transformation, en instruction préparée est le seul sous-ensemble d'entre eux.
Parfois, nous avons à composer une requête avec les données, mais si tous les bits de données est correctement mis en forme en fonction de son type - rien de mal pourrait se produire.
Ainsi, par exemple, par défaut AOP ne pas utiliser les requêtes préparées , mais plutôt de composer la requête courante. Mais parce qu'il substitue à chaque espace réservé avec les données correctement formatées, rien de mal ne peut arriver.
Mais vous voulez dire à PDO pour faire la voie droite, à utiliser de vraies déclarations préparées à l'avance, vous devez définir ce paramètre:
$dbh->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
Veuillez également noter que le formatage n'est pas à confondre avec l'échappement. Mise en forme implique beaucoup plus d'actions que d'idiot de s'échapper. Donc, n'essayez pas de manuel d'échapper à la maison, au moins jusqu'à ce que vous apprenez à connaître chaque règle de mise en forme pour chaque requête distinct de la partie.
La seule chose que j'ai à ajouter, toujours omis dans chaque manuel:
Les instructions préparées peuvent protéger seulement les données, mais ne peut pas défendre le programme lui-même.
Donc, une fois que nous avons à ajouter, disons, une dynamique identifiant - un nom de champ, par exemple, les requêtes préparées ne peut pas nous aider.
J'ai expliqué la question récemment, donc je ne vais pas me répéter.