2010-10-28 7 views
11

Je comprends que la bonne façon de protéger une base de données contre l'injection SQL est d'utiliser des instructions préparées. Je voudrais comprendre comment déclarations préparées protègent mon DB.En PHP, comment PDO protège-t-il des injections SQL? Comment fonctionnent les déclarations préparées?

Pour les démarreurs, les instructions préparées sont-elles identiques aux "requêtes paramétrées"? Par exemple, je colle sous mon code pour l'insertion d'un nouvel utilisateur dans une table utilisateur. Est-ce sécurisé? Comment fonctionne PDO pour le sécuriser? Est-ce que quelque chose de plus doit être fait pour sécuriser le db de l'injection?

Dans 'Class_DB.php':

class DB { 
private $dbHost; 
private $dbName; 
private $dbUser; 
private $dbPassword; 
function __construct($dbHost, $dbName, $dbUser, $dbPassword) { 
    $this->dbHost=$dbHost; 
    $this->dbName=$dbName; 
    $this->dbUser=$dbUser; 
    $this->dbPassword=$dbPassword; 
} 
function createConnexion() { 
    return new PDO("mysql:host=$this->dbHost;dbName=$this->dbName", $this->dbUser, $this->dbPassword); 
} 
} 

Dans 'DAO_User.php':

require_once('Class_DB.php'); 

class DAO_User { 
private $dbInstance; 
function __construct($dbInstance){ 
    $this->dbInstance=$dbInstance; 
} 
function createUser($user){ 
    $dbConnection=$this->dbInstance->createConnexion(); 
    $query=$dbConnection->prepare("INSERT INTO users (userName, hashedPassword, userEmail) VALUES (?,?,?)"); 
    $query->bindValue(1, $user->userName); 
    $query->bindValue(2, $user->hashedPassword); 
    $query->bindValue(3, $user->userEmail); 
    $query->execute(); 
} 
} 

Merci,

JDelage

+2

connexes: http://stackoverflow.com/questions/134099/are-pdo-prepared-statements-sufficient-to-prevent-sql-injection –

+0

Merci Haim, les réponses réponse troelskn ma question. – JDelage

+0

'les instructions préparées sont-elles identiques aux" requêtes paramétrées "?' Oui. Aussi, permettez-moi de vous signaler un autre problème lié à l'injection sql, décrit dans ma réponse précédente: http://stackoverflow.com/questions/2993027/in-php-when-submitting-strings-to-the-db-should- i-take-care-of-illegal-characters/2995163 # 2995163 car nous avons non seulement des données insérées dans nos requêtes, et les déclarations préparées ne l'aideraient pas –

Répondre

20

Ok, j'ai trouvé la réponse à ma question dans cette question connexe: Are PDO prepared statements sufficient to prevent SQL injection?

Merci à Haim pour avoir signalé Q pour moi.

En termes non techniques, voici comment les déclarations préparées à protéger de l'injection:

Lorsqu'une requête est envoyée à une base de données, il est généralement envoyé sous forme de chaîne. Le moteur db va essayer d'analyser la chaîne et de séparer les données des instructions, en se basant sur les guillemets et la syntaxe. Donc, si vous envoyez "SELECT * WHERE" données soumises par l'utilisateur "EQUALS" nom de la ligne de la table ', le moteur sera en mesure d'analyser l'instruction.

Si vous autorisez un utilisateur à entrer ce qui sera envoyé à l'intérieur des 'données soumises par l'utilisateur', alors il peut inclure quelque chose comme '... "OU SI 1 = 1 ERASE DATABASE'. La façon dont le PDO fonctionne est qu'il envoie séparément l'instruction (prepare ("INSERT INTO ...)) et les données. Les données sont envoyées séparément, clairement comprises comme étant des données et des données uniquement. Le moteur db n'essaye même pas d'analyser le contenu de la chaîne de données pour voir s'il contient des instructions, et aucun snipet de code potentiellement dommageable n'est considéré.

+2

Je sais que c'est une vieille réponse, mais cela devrait être dans chaque entrée niveau livre de texte sur PHP et bases de données. Très clair et facile à comprendre! – MaDaHoPe

3

Voilà mon point de vue quelque peu limitée sur la importe ...

Une instruction préparée est compilée sur le serveur de base de données avec des espaces réservés pour l'entrée de variable.

Lorsque vous liez un paramètre, vous indiquez au DB les valeurs à utiliser lorsque vous exécutez la requête. Il passera ensuite la valeur à l'instruction compilée.

La différence entre les paramètres de liaison et l'injection de chaîne simple est qu'avec la première, la valeur n'est pas interpolée mais plutôt affectée. Pendant l'exécution, le SGBD frappe un espace réservé et demande la valeur à utiliser. De cette façon, il n'y a aucune chance que les caractères de citation ou d'autres méchants se glissent leur chemin dans la déclaration réelle.

2

Sans utiliser d'instructions préparées, vous ne pouviez pas utiliser d'espace réservé (?) Dans votre requête. Au lieu de cela, vous devez inclure la valeur que vous souhaitez insérer directement dans l'instruction SQL. Cela entraînerait une instruction SQL différente pour chaque insertion (mauvaise pour les performances) et si vous ne faites pas attention aux chaînes que vous insérez dans l'instruction, vous pouvez également obtenir une instruction qui fait autre chose que ce que vous vouliez (par exemple L'injection SQL pourrait arriver). Cette situation est similaire à celle d'une fonction Javascript qui effectue un code fixe avec des paramètres d'entrée variables, plutôt que de coller les paramètres d'entrée dans la source Javascript, puis de l'évaluer.

-1

votre source est sécurisée contre sqli attaque.

c'est un exemple et n'est pas sécurisé lorsque vous sélectionnez un utilisateur dans votre base de données.

// example: localhost/user.php?username=admin 

$getdata = $_GET['username']; 

$dbConnection=$this->dbInstance->createConnexion(); 
$query=$dbConnection->prepare("SELECT * FROM users WHERE username=".$getdata."); 

// PHP simple 
+0

Je me demande qui serait upvote cette réponse qui a complètement raté la question posée ici –

Questions connexes