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(). If you wish to insert binary data you must use this function.

mysql_real_escape_string() appelle une fonction de la bibliothèque MySQL du même nom, qui ajoute un slashe aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a.

Vous devez toujours (avec quelques rares exceptions) utiliser cette fonction pour protéger vos données avant de les insérer dans la base. Si vous avez magic_quotes_gpc d'activé, vous devez d'abord utiliser la fonction stripslashes() sur vos données. Si vous n'utilisez pas celà, vous devez vous protégrer vous-même des attaques par injection SQL. Voici un exemple :

Exemple 1. 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 1=1";

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

La requête envoyée à MySQL :

SELECT * FROM users WHERE name='fred' AND password='' OR 1=1

Celà permet à n'importe qui de s'identifier sans mot de passe valide ! L'utilisation de la fonction mysql_real_escape_string() sur chaque variable prévient celà.

<?php
/**
* Applique la fonction stripslashes recursivement
*/
function stripslashes_deep($value)
{
    
$value = is_array($value) ?
                
array_map('stripslashes_deep', $value) :
                
stripslashes($value);

    return
$value;
}

/**
* Protège la variable avant l'insertion
*/
function quote_smart($value)
{
    
// Stripslashes si nécessaire
    
if (get_magic_quotes_gpc()) {
        
$value = stripslashes_deep($value);
    }

    
// Protection si ce n'est pas un entier
    
if (!is_int($value)) {
        
$value = "'" . mysql_real_escape_string($value) . "'";
    }

    return
$value;
}

// Connexion
$link = mysql_connect('localhost', '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);
?>

Votre requête est maintenant sécurisé quelques que soient les données entrées par l'utilisateur !

Note : mysql_real_escape_string() n'échappe ni %, ni _. Ce sont des jokers en MySQL si non liés par des guillemets.

Voir aussi mysql_client_encoding(), addslashes(), ainsi que la directive magic_quotes_gpc.