Bonjour,
La fonction PHP mysqli_real_escape_string() permet d'échapper les apostrophes et autres signes pouvant induire en erreur un serveur MySQL à exécuter sans l'avoir désiré, une sous requête MySQL. On nomme ce type d'attaque : une injection SQL.
Le principe est d'introduire une requête à l'intérieur d'une autre requête afin soit de supprimer des données MySQL ou d'obtenir une réponse toujours vrai quelque soit les argument suivants, cette réponse vrai est souvent utilisé dans les authentifications.
Cependant, bien que la fonction mysqli_real_escape_string() soit primordiale dans les anciens développements, elle a rapidement été remplacée par une autre méthode de développement, que l'on nomme PDO.
Le principe du PDO est de construire une requête de manière sécurisé et indépendante du moteur de base de données SQL utilisé. Le second point est que l'on vas encapsuler une suite de requêtes MySQL et effectuer ou non à la fin, un commit afin d'exécuter ou pas le traitement qui a été fait. Ainsi, s'il y a un problème pendant l'exécution, les services vont "revenir en arrière" (rollback) comme si rien n'avait été fait.
Grosso modo, dans le principe de base "en français" ça fonctionne ainsi :
Code : Tout sélectionner
ligne_sql = preparation("INSERT INTO table (nom, age) VALUES ( :nom, :age);
construction( ligne_sql, tableau(:nom => $nom, :age => $age))
execution(construction)
Voilà un exemple de code avec une fonction perso que j'utilise afin de simplifier l'écriture :
function perso_pdo_query($query, $data='')
{
global $pdo;
if(empty($data))
{
$sth = $pdo->query($query);
}else{
$data = unstrip_array($data);
$sth = $pdo->prepare($query);
$sth->execute($data);
}
return $sth;
}
$sql= "INSERT INTO table (nom, age) VALUES ( :nom, :age);";
perso_pdo_query($sql, array(':nom' => $nom, ':age' => $age));
Ainsi, je n'ai plus besoin de me soucier si âge est un nombre ou non, inutile d'encadrer les valeurs. De plus, si la personne met dans son âge une requête MySQL, la préparation et la construction de la requête n'interprétera pas la valeur comme une sous requête injectée. Le serveur PHP/MySQL ne se font ainsi plus induire en erreur.
La connexion MySQL a préalablement été effectuée en PDO et placée dans l’objet de nom $pdo que je réutilise dans la fonction en l'important depuis le global.
Voilà un code de connexion en PDO :
Code : Tout sélectionner
function perso_pdo_connect()
{
global $pdo;
try
{
$pdo = new PDO('mysql:host=<host>;dbname=<base>', '<user>', '<password>',
array(PDO::ATTR_PERSISTENT => true));
}
catch(Exception $e)
{
echo("Erreur MySQL n° ".$e->getCode()." : ".$e->getMessage());
exit();
}
}
Pour démarrer une transaction MySQL avec PDO, voilà un autre code :
Code : Tout sélectionner
try
{
$pdo->beginTransaction();
// le code mysql ici
$pdo->commit();
}catch (PDOException $e){
//sinon on retourne l'erreur MySQL à l'admin du site : $e
}
}
Voilà grossièrement
starscot a écrit :les entrées protégées avec cette fonction apparaissent comme vide (ex. pseudo) Est-ce normal ou faut-il protéger autrement ?
Non ce n'est pas normal, vous devriez toujours pouvoir accéder aux informations que vous enregistrés
Aussi, je déplace votre question dans la partie développement car ça ne concerne pas directement le support technique