Manuel PHP

mysql_real_escape_string

(PHP 4 >= 4.3.0, PHP 5, PECL mysql:1.0)

mysql_real_escape_string — Protège les caractères spéciaux d'une commande SQL

Description

string mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier ] )

mysql_real_escape_string() protège les caractères spéciaux de la chaîne unescaped_string , en prenant en compte le jeu de caractères courant de la connexion link_identifier . Le résultat peut être utilisé sans problème avec la fonction mysql_query(). Si des données binaires doivent être insérées, cette fonction doit être utilisée.

mysql_real_escape_string() appelle la fonction mysql_escape_string() de la bibliothèque MySQL qui ajoute un slash aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a.

Cette fonction doit toujours (avec quelques exceptions) être utilisée pour protéger vos données avant d'envoyer la requête à MySQL.

Liste de paramètres

unescaped_string

La chaîne à échapper.

link_identifier

La connexion MySQL. S'il n'est pas spécifié, la dernière connexion ouverte avec la fonction mysql_connect() sera utilisée. Si une telle connexion n'est pas trouvée, la fonction tentera d'ouvrir une connexion, comme si la fonction mysql_connect() avait été appelée sans argument. Si aucune connexion n'est trouvée ou établie, une alerte E_WARNING est générée.

Valeurs de retour

Retourne la chaîne échappée, ou FALSE si une erreur survient.

Exemples

Example#1 Exemple simple avec mysql_real_escape_string()

  1. <?php
  2. // Connexion
  3. $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')  
  4. OR die(mysql_error());  
  5.  
  6. // Requête
  7. $query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",  
  8. mysql_real_escape_string($user),  
  9. mysql_real_escape_string($password));  
  10. ?> 

Example#2 Un exemple d'attaque par injection SQL

  1. <?php
  2. // Demande à la base de vérifier si un utilisateur correspond
  3. $query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";  
  4. mysql_query($query);  
  5.  
  6. // Nous ne vérifions pas $_POST['password'], il peut contenir ce que l'utilisateur veut ! Par exemple :
  7. $_POST['username'] = 'aidan';  
  8. $_POST['password'] = "' OR ''='";  
  9.  
  10. // Cela signifie que la requête envoyée à MySQL sera :
  11. echo $query;  
  12. ?> 

La requête envoyée à MySQL :

SELECT * FROM users WHERE user='aidan' AND password='' OR ''=''

Cela permet à n'importe qui de s'identifier sans mot de passe valide.

Example#3 Meilleure pratique

L'utilisation de la fonction mysql_real_escape_string() sur chaque variable évite les injections SQL. Cet exemple démontre la méthode la plus propre pour envoyer une requête à la base, indépendamment de votre configuration des guillemets magiques.

  1. <?php
  2.  
  3. if (isset($_POST['product_name']) && isset($_POST['product_description']) && isset($_POST['user_id'])) { 
  4.    // Connect
  5.  
  6.    $link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password'); 
  7.  
  8.    if(!is_resource($link)) { 
  9.  
  10.       echo "Échec de la connexion au serveur\n"; 
  11.       // ... historisation de l'erreur
  12.  
  13.    } else { 
  14.  
  15.       // Annule les effets magic_quotes_gpc/magic_quotes_sybase sur ces variables si ON.
  16.  
  17.       if(get_magic_quotes_gpc()) { 
  18.          if(ini_get('magic_quotes_sybase')) { 
  19.             $product_name      = str_replace("''", "'", $_POST['product_name']); 
  20.             $product_description = str_replace("''", "'", $_POST['product_description']); 
  21.          } else { 
  22.             $product_name      = stripslashes($_POST['product_name']); 
  23.             $product_description = stripslashes($_POST['product_description']); 
  24.          } 
  25.       } else { 
  26.          $product_name      = $_POST['product_name']; 
  27.          $product_description = $_POST['product_description']; 
  28.       } 
  29.  
  30.       // Faire une requête sécurisée
  31.       $query = sprintf("INSERT INTO products (`name`, `description`, `user_id`) VALUES ('%s', '%s', %d)", 
  32.                mysql_real_escape_string($product_name, $link), 
  33.                mysql_real_escape_string($product_description, $link), 
  34.                $_POST['user_id']); 
  35.  
  36.       mysql_query($query, $link); 
  37.  
  38.       if (mysql_affected_rows($link) > 0) { 
  39.          echo "Produit inséré\n"; 
  40.       } 
  41.    }  
  42. } else { 
  43.    echo "Remplissez le formulaire proprement\n";  
  44. }  
  45. ?> 

La requête s'exécute maintenant correctement et les attaques par injection SQL ne fonctionnent plus.

Notes

Note: Une connexion MySQL est nécessaire avant d'utiliser la fonction mysql_real_escape_string(), sinon, une erreur de niveau E_WARNING sera générée, et FALSE sera retourné. Si link_identifier n'est pas défini, la dernière connexion MySQL est utilisée.

Note: Si magic_quotes_gpc est activée, appliquez d'abord la fonction stripslashes() à vos données. Utiliser cette fonction sur des données qui ont déjà été protégées, les protègera une deuxième fois.

Note: Si cette fonction n'est pas utilisée pour protéger vos données, la requête sera vulnérable aux attaques par injection SQL.

Note: mysql_real_escape_string() n'échappe ni %, ni _. Ce sont des jokers en MySQL si combinés avec LIKE, GRANT, ou REVOKE.

L'éditeur javascript - CSS - Gentoo - Tutoriaux PHP - Tutoriels PHP - Php - Breizh Blog