web-dev-qa-db-fra.com

Alternative à mysql_real_escape_string sans connexion à la base de données

J'aimerais avoir une fonction se comportant comme mysql_real_escape_string sans se connecter à la base de données car il me faut parfois faire des tests à sec sans connexion à la base de données. mysql_escape_string est obsolète et n'est donc pas souhaitable. Certaines de mes découvertes:

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

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

86
Viet

Il est impossible d'échapper en toute sécurité à une chaîne sans connexion à la base de données. mysql_real_escape_string() et les instructions préparées nécessitent une connexion à la base de données pour pouvoir échapper à la chaîne à l'aide du jeu de caractères approprié; sinon, les attaques par injection SQL sont toujours possibles à l'aide de caractères multi-octets.

Si vous êtes seulement en test, vous pouvez également utiliser mysql_escape_string(), ce n'est pas garanti à 100% contre les attaques par injection SQL, mais il est impossible de construire quelque chose de plus sûr sans connexion à la base de données.

72
too much php

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

Dans cet esprit, la fonction indiquée dans le deuxième lien que vous avez posté doit 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);
}
60
zombat

Contrairement à 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 qu'une personne plus informée que moi pourra me dire pourquoi le code ci-dessus ne fonctionne pas ...

25
too much php

Des recherches ultérieures, j'ai trouvé:

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

Correctif de sécurité:

Une faille de sécurité liée à l'injection SQL a été détectée dans le traitement de l'encodage sur plusieurs octets. Le bogue était sur le serveur et analysait incorrectement la chaîne échappée avec la fonction API C mysql_real_escape_string ().

Cette vulnérabilité a été découverte et signalée par Josh Berkus et Tom Lane dans le cadre de la collaboration entre projets du consortium OSDB en matière de sécurité. Pour plus d'informations sur l'injection SQL, veuillez consulter le texte suivant.

Discussion. Une faille de sécurité liée à l’injection SQL a été découverte lors du traitement de l’encodage sur plusieurs octets. Une faille de sécurité liée à une injection SQL peut inclure une situation dans laquelle, lorsqu'un utilisateur a fourni 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é, lorsqu’on utilise l’échappement avec un jeu de caractères (par exemple, addedlashes () 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 includeslashes () ne peut pas empêcher les attaques par injection SQL. Il est impossible de résoudre ce problème côté serveur. La meilleure solution est que les applications utilisent l'échappement basé sur le 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 (). En conséquence, même lorsque la fonction mysql_real_escape_string () tenant compte du jeu de caractères était utilisée, l'injection SQL était possible. Ce bug a été corrigé.

Contournements. Si vous ne parvenez pas à mettre à niveau MySQL vers une version qui inclut le correctif pour le bogue dans l'analyse syntaxique de 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, dans lequel 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). , selon votre système). (Bogue n ° 8378, CVE-2006-2753)

Voir aussi le bogue n ° 8303.

6
Viet