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

Exemple 1609. 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 ));
?>

Exemple 1610. 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 que l'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 user='aidan' AND password='' OR ''=''

    

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


Exemple 1611. 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 .

<?php

if (isset( $_POST [ 'product_name' ]) && isset( $_POST [ 'product_description' ]) && isset( $_POST [ 'user_id' ])) {
    
// Connect

    
$link  mysql_connect ( 'mysql_host' 'mysql_user' 'mysql_password' );

    if(!
is_resource ( $link )) {

        echo 
"Échec de la connexion au serveur\n" ;
        
// ... historisation de l'erreur

    
} else {

        
// Annule les effets magic_quotes_gpc/magic_quotes_sybase sur ces variables si ON.

        
if( get_magic_quotes_gpc ()) {
            if(
ini_get ( 'magic_quotes_sybase' )) {
                
$product_name         str_replace ( "''" "'" $_POST [ 'product_name' ]);
                
$product_description  str_replace ( "''" "'" $_POST [ 'product_description' ]);
            } else {
                
$product_name         stripslashes ( $_POST [ 'product_name' ]);
                
$product_description  stripslashes ( $_POST [ 'product_description' ]);
            }
        } else {
            
$product_name         $_POST [ 'product_name' ];
            
$product_description  $_POST [ 'product_description' ];
        }

        
// Faire une requête sécurisée
        
$query  sprintf ( "INSERT INTO products (`name`, `description`, `user_id`) VALUES ('%s', '%s', %d)" ,
                    
mysql_real_escape_string ( $product_name $link ),
                    
mysql_real_escape_string ( $product_description $link ),
                    
$_POST [ 'user_id' ]);

        
mysql_query ( $query $link );

        if (
mysql_affected_rows ( $link ) >  0 ) {
            echo 
"Produit inséré\n" ;
        }
    }
} else {
    echo 
"Remplissez le formulaire proprement\n" ;
}
?>

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 .

Voir aussi

mysql_client_encoding()addslashes()stripslashes()The magic_quotes_gpc directiveThe magic_quotes_runtime directive