mysql_real_escape_string

(PHP 4 >= 4.3.0, PHP 5)

mysql_real_escape_string --  Protège les caractères spéciaux d'une commande SQL pour MySQL

Description

string mysql_real_escape_string ( string unescaped_string [, resource link_identifier] )

unescaped_string

La chaîne à échapper

link_identifier (optional)

La ressource de connexion MySQL

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 slashe aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a.

Exemple 1. Exemple simple avec mysql_real_escape_string()

<?php
// Connexion
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
    OR die(
mysql_error());

// Requête
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
            
mysql_real_escape_string($user),
            
mysql_real_escape_string($password));
?>

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

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.

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.

Exemple 2. Un exemple d'attaque par injection SQL

<?php
// Demande à la base de vérifier si un utilisateur correspond
$query = "SELECT * FROM users WHERE user='{$_POST['username']}' AND password='{$_POST['password']}'";
mysql_query($query);

// Nous ne vérifions pas $_POST['password'], il peut contenir ce quel'utilisateur veut ! Par exemple :
$_POST['username'] = 'aidan';
$_POST['password'] = "' OR ''='";

// Cela signifie que la requête envoyée à MySQL sera :
echo $query;
?>

La requête envoyée à MySQL :

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

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

Exemple 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 de guillemets magiques.

<?php
// Protège la variable

function quote_smart($value)
{
    
// Stripslashes
    
if (get_magic_quotes_gpc()) {
        
$value = stripslashes($value);
    }
    
// Protection si ce n'est pas un entier
    
    
if (!is_numeric($value)) {
        
$value = "'" . mysql_real_escape_string($value) . "'";
    }

    return
$value;
}

// Connexion
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
    OR die(
'Could not connect: ' . mysql_error());

// Fabrication d'une requête sécurisée
$query = sprintf("SELECT * FROM users WHERE user=%s AND password=%s",
            
quote_smart($_POST['username']),
            
quote_smart($_POST['password']));

mysql_query($query);
?>

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

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

Voir aussi mysql_client_encoding(), addslashes(), stripslashes() ainsi que les directives magic_quotes_gpc et magic_quotes_runtime.