2009-07-22 5 views
77

Je voudrais avoir une fonction se comporter comme mysql_real_escape_string sans se connecter à la base de données comme je dois faire des tests à sec sans connexion DB. mysql_escape_string est obsolète et n'est donc pas souhaitable. Certaines de mes conclusions:Alternative à mysql_real_escape_string sans se connecter à la base de données

http://www.gamedev.net/community/forums/topic.asp?topic_id=448909

http://w3schools.invisionzone.com/index.php?showtopic=20064

+1

+1 J'écris moi-même la classe MySQL et j'utilise mysql_real_escape_string() à des fins de liaison de paramètres. J'évite d'utiliser mysqli car tous les hébergeurs ne le supportent pas. J'évite également la bibliothèque de multi-dossier et de multi-classe. Ce dont j'ai besoin, c'est juste une classe unique soignée et propre. Je vous remercie! – Viet

+0

http://ca2.php.net/manual/fr/function.addslashes.php – mpen

+0

+1 pour moi aussi. Mon cas d'utilisation est un APi SugarCRM dans lequel j'ai besoin de pousser des fragments de SQL vers l'instance distante de SugarCRM via l'API. Nasty bien que ce soit, c'est ce que je dois travailler avec (aller frapper quelques têtes de dev SugarCRM ensemble). J'ai besoin d'échapper des chaînes dans SQL dans l'application qui utilise l'API et qui est totalement séparée de la base de données derrière l'instance de SugarCRM. – Jason

Répondre

64

Il est impossible d'échapper en toute sécurité une chaîne sans connexion DB. mysql_real_escape_string() et les instructions préparées nécessitent une connexion à la base de données afin qu'elles puissent échapper à la chaîne en utilisant le jeu de caractères approprié. Dans le cas contraire, les attaques par injection SQL sont toujours possibles à l'aide de caractères multi-octets.

Si vous ne test, vous pouvez aussi bien utiliser mysql_escape_string(), ce n'est pas 100% garanti contre les attaques par injection SQL, mais il est impossible de construire quoi que ce soit plus sûr sans connexion DB.

+1

+1 Merci pour la note. Je ne suis pas très sûr de savoir comment tester les attaques par injection SQL à l'aide de caractères multi-octets. – Viet

+2

J'ai reçu un code ancien à mettre à jour. Il utilise 'mysql_escape_string' sans connexion (essayant toujours de comprendre pourquoi). Puisque cette fonction est obsolète, je me demande comment je peux la remplacer. Il semble certainement raisonnable que l'on puisse spécifier le "jeu de caractères approprié" dans n'importe quelle fonction qui le remplace sans ouvrir de connexion. – JohnK

+0

@JohnK, c'est "correct" dans la mesure où PHP pourrait être appelé ainsi. :-) A propos du paramètre $ connection: "Facultatif: Spécifie la connexion MySQL Si non spécifié, la dernière connexion ouverte par mysql_connect() ou mysql_pconnect() est utilisée." –

53

Eh bien, selon la page de référence de la fonction mysql_real_escape_string: Fonction bibliothèque « mysql_real_escape_string() appelle MySQL mysql_real_escape_string, qui échappe aux caractères suivants: \ x00 \ n , \ r, \, », "et \ X1A."

dans cet esprit, la fonction donnée dans le second lien que vous avez posté devrait faire exactement ce dont vous avez besoin:

function mres($value) 
{ 
    $search = array("\\", "\x00", "\n", "\r", "'", '"', "\x1a"); 
    $replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z"); 

    return str_replace($search, $replace, $value); 
} 
+6

Merci. Je vous suggère quelque chose d'autre: évasion fonction ($ aQuery) { strtr retour ($ aQuery, tableau ( "\ x00" => '\ x00', "\ n" => '\ n', "\ r" => '\ r', '\\' => '\\\\', "'" => "\'", '"' => '\"', " \ x1a "=> '\ x1a' )); } – Viet

+1

pourquoi \ x1a est remplacé par \\\ x1a plutôt que \\ x1a? Est-ce une faute de frappe? –

+13

-1 Ceci est extrêmement dangereux. Si la connexion à la base de données utilise un jeu de caractères codés sur plusieurs octets, de simples remplacements d'octets comme celui-ci peuvent entraîner une corruption des données (y compris l'échappement de caractères/citations), ce qui peut être délibérément exploité par un attaquant malveillant. – eggyal

22

En opposition directe à mon autre réponse, cette fonction suivante est probablement sûre, même avec des caractères multi-octets.

// replace any non-ascii character with its hex code. 
function escape($value) { 
    $return = ''; 
    for($i = 0; $i < strlen($value); ++$i) { 
     $char = $value[$i]; 
     $ord = ord($char); 
     if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126) 
      $return .= $char; 
     else 
      $return .= '\\x' . dechex($ord); 
    } 
    return $return; 
} 

J'espère que quelqu'un de plus compétent que moi peut me dire pourquoi le code ci-dessus ne fonctionnera pas ...

+0

+1 Merci pour l'effort supplémentaire. Je vais en savoir plus sur les injections SQL multi-octets. – Viet

+0

Je suppose que cela devrait être $ return. = '\ X'. dechex ($ ord); à la place – Viet

+1

En règle générale, je préfère utiliser '\\' même dans les chaînes à guillemets simples, juste parce qu'un simple '\' peut affecter le caractère suivant si vous ne faites pas attention. Je suis probablement juste redevenu un OCD. –

5

De plus amples recherches, j'ai trouvé:

http://dev.mysql.com/doc/refman/5.1/en/news-5-1-11.html

Correction de sécurité:

Un trou de sécurité d'injection SQL a été détecté dans le traitement de codage multi-octets. Le bogue se trouvait sur le serveur, analysant de manière incorrecte la chaîne échappée avec la fonction de l'API C mysql_real_escape_string().

Cette vulnérabilité a été découverte et rapportée par Josh Berkus et Tom Lane dans le cadre de la collaboration inter-projets sur la sécurité du consortium OSDB. Pour plus d'informations sur l'injection SQL, consultez le texte suivant.

Discussion. Un trou de sécurité d'injection SQL a été trouvé dans le traitement de codage multi-octets. Un trou de sécurité d'injection SQL peut inclure une situation où, lorsqu'un utilisateur fournit des données à insérer dans une base de données, l'utilisateur peut injecter des instructions SQL dans les données que le serveur va exécuter. En ce qui concerne cette vulnérabilité, lorsque l'échappement character set-aware est utilisé (par exemple, addslashes() en PHP), il est possible de contourner l'échappement dans certains jeux de caractères multi-octets (par exemple, SJIS, BIG5 et GBK). Par conséquent, une fonction telle que addslashes() ne peut pas empêcher les attaques par injection SQL. Il est impossible de résoudre ce problème du côté serveur. La meilleure solution consiste pour les applications à utiliser l'échappement par jeu de caractères offert par une fonction telle que mysql_real_escape_string().

Cependant, un bug a été détecté dans la façon dont le serveur MySQL analyse la sortie de mysql_real_escape_string().Par conséquent, même lorsque la fonction mysql_real_escape_string() a été utilisée, l'injection SQL était possible. Ce bug a été corrigé.

Solutions de contournement. Si vous ne parvenez pas à mettre à niveau MySQL vers une version qui inclut la correction du bogue dans l'analyse mysql_real_escape_string(), mais exécutez MySQL 5.0.1 ou une version ultérieure, vous pouvez utiliser le mode SQL NO_BACKSLASH_ESCAPES comme solution de contournement. (Ce mode a été introduit dans MySQL 5.0.1.) NO_BACKSLASH_ESCAPES active un mode de compatibilité standard SQL, où la barre oblique inverse n'est pas considérée comme un caractère spécial. Le résultat sera que les requêtes échoueront.

Pour définir ce mode pour la connexion en cours, entrez l'instruction SQL suivante:

SET sql_mode='NO_BACKSLASH_ESCAPES'; 

Vous pouvez également définir le mode globalement pour tous les clients:

SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES'; 

Ce mode SQL peut également être activé automatiquement lorsque le serveur démarre en utilisant l'option de ligne de commande --sql-mode = NO_BACKSLASH_ESCAPES ou en définissant sql-mode = NO_BACKSLASH_ESCAPES dans le fichier d'options du serveur (par exemple, my.cnf ou my.ini, en fonction de votre système) . (Bogue n ° 8378, CVE-2006-2753)

Voir également le bogue n ° 8303.

+1

Cela a été corrigé depuis longtemps. –

+1

Prenez également garde que 'NO_BACKSLASH_ESCAPES' [introduit d'autres vulnérabilités] (http://stackoverflow.com/a/23277864/623041). – eggyal

+2

Correction en 5.1.11 - Le lien était cassé, voici l'archive: https://web.archive.org/web/20120501203047/http://dev.mysql.com:80/doc/refman/5.1/ fr/news-5-1-11.html – Bastion

Questions connexes