Qu'est-ce que mysql real escape string() fait qui addslashes() ne fait pas?
Pourquoi avons-nous besoin de fonctions spécifiques aux DB comme mysql_real_escape_string()? Que peut-il faire si addslashes() ne le fait pas?
ignorant pour le moment l'alternative supérieure des requêtes paramétrées, est-ce qu'une webapp qui utilise addslashes() exclusivement est encore vulnérable à L'injection SQL, et si oui, comment?
11 réponses
Addslashes n'est généralement pas assez bon lorsqu'il s'agit de chaînes encodées multibytes.
Il ajoute des barres obliques pour:
\x00, \n, \r, \, ', " and \x1a. characters.
où addslashes ajoute seulement slashes à
' \ and NUL
article de Ilias est aussi assez détaillé sur sa fonctionnalité
la réponse fortement rétrograde de gs est en fait un peu juste.
SQL Standard utilise le doublage pour échapper à une apostrophe littérale. L'utilisation non standard de backlashs pour échapper à MySQL est le paramètre par défaut, mais il peut être désactivé et l'est souvent, en particulier dans sql_mode ANSI.
dans ce cas, seule la syntaxe doublée fonctionnera, et toute application que vous avez en utilisant addslashes (ou une autre méthode d'échappement ad-hoc) sera cassée. mysql_real_escape_string utilisera échapper quelle que soit la méthode le meilleur pour la connexion sql_mode.
la question de l'encodage multibyte est également importante si vous utilisez toujours ces encodages asiatiques méchants qui réutilisent les 128 caractères inférieurs, mais alors vraiment vous voulez utiliser UTF-8 à la place. \ n-échapper, d'un autre côté, n'est pas un problème puisque MySQL peut parfaitement faire face à une nouvelle ligne brute dans une déclaration.
mysql_real_escape_stringbeaucoup plusaddslashes
ne.
addslashes fonctionne en ascii pur, sans rien savoir de la base de données. Il s'échappe:
'
→\'
"
→\"
\
→\
- ASCII
0
→.
mysql_real_escape_string'objectif est de "créer un cadre juridique SQL chaîne que vous pouvez utiliser dans une instruction SQL."mysql_real_escape_string prend en compte le jeu de caractères courant de la connexion (qui est pourquoi vous devez toujours passer un valide $mysql objet).
Il n'est le suivant (tiré de la documentation de l'API C de MySQL):
- Code:
\
,'
,"
, ASCII0
,\n
,\r
etControl+Z
d'une manière qui ne cause pas de problèmes - assure un
0
byte termine la chaîne (dans l'api C) - peut effectuer une conversion multibyte (ascii) en wide character si le DB lié à in $mysql utilise un wide character set.
Je ne sais pas vraiment comment PHP stocke les chaînes en interne, mais le point est que tout ceci est disponible pour PHP quand vous utilisez mysql_real_escape_string
. Je suppose que le principal point de différence est mysql_real_escape_string
considère le jeu de caractères de la connexion, où addslashes
ne peut pas (il ne sait même pas ce que DB vous êtes connecté).
somedb_real_escape_string()
une base de données spécifique, addslashes()
ne l'est pas.
dans le cas de MySQL cela signifie:
appels mysql_real_escape_string() La fonction bibliothèque de MySQL mysql_real_escape_string, qui ajoute des barres obliques inverses à la suivante caractères: \x00, \n, \r, \, ', " et \x1a.
(à Partir du manuel.)
Pourquoi avons-nous besoin de fonctions spécifiques aux DB comme mysql_real_escape_string()?
en fait, la plupart du temps nous ne le faisons pas.
Cette fonction est nécessaire pour quelques encodages extrêmement rares, et pour prétifier mysql logs et dumps un peu.
une webapp qui utilise addslashes () exclusivement est-elle encore vulnérable à L'injection SQL?
tant qu'il utilise un jeu de caractères à un seul octet ou utf8 -c'est parfaitement sûr avec addslashes().
que peut-il faire si addslashes() ne le fait pas?
il peut protéger SQL chaîne de caractères littérale en cas de quelques encodages rares.
cependant, il ne peut pas le faire tout seul. un encodage correct doit être défini à l'aide de mysql_set_charset()
fonction d'abord. Si cette fonction n'a pas été utilisée,mysql_real_escape_string()
se comporterait exactement de la même façon que .
la seule vraie différence que je connaisse est que mysql_real_escape_string () prendra en considération le jeu de caractères de la base de données lors de l'évasion de la chaîne de saisie. Aucune des deux fonctions n'échappera aux caractères génériques % et_, ce qui laisse encore le script ouvert à une injection SQL.
Selon manuel PHP:
mysql_real_escape_string() appelle la fonction de bibliothèque mysql_real_escape_string de MySQL, qui prépose des antislashs aux caractères suivants: \x00, \n, \r,\,', " et \x1a.
la fonction mysql_real_escape_string de PHP va, plus ou moins,demander à mysql de ce personnage(s) doit être échappés, où la fonction addslashses ajoutera simplement un antislash devant et n'importe quel caractère simple quote ('), double quote ("), antislash () ou NULL (l'octet NULL).
les deux effets pratiques sont, addslashs a tendance à ne pas bien fonctionner avec les caractères multi-octets, et, plus important encore, en demandant à mysql quels caractères doivent être échappés, vous évitez une possibilité la compatibilité future. Utiliser assslashes est un peu comme le codage dur d'un couple de caractères spécifiques dans la séquence d'évasion.
il est supposé échapper aux chaînes pour MySQL d'une manière que les autres installations de citation ne le font pas.
il est toutefois préférable de utilisez l'interface mysqli, et utilisez des requêtes préparées paramétrées au lieu d'essayer de s'assurer que toutes vos chaînes sont correctement échappées. L'utilisation de requêtes paramétrées élimine la nécessité d'un tel travail de chaîne désordonnée et atténue fortement le risque d'injection de SQL.
Edit: je vais clarifier un peu pourquoi je considère citer un mauvais idée: il est facile d'oublier quand et où vous devez citer - si votre variable doit être une chaîne ou un nombre, si elle a déjà été citée, etc. Une requête paramétrée n'a aucun de ces problèmes, et le besoin de citer est complètement écartées.
selon ma compréhension mysql_real_escape_string () faire le travail plus précisément, car il communique avec la db pour vérifier d'abord que ce qui doit être encodé et puis encoder en conséquence, n'est-ce pas? Donc là pour cela travaillent plus efficacement
pourquoi vous voulez d'abord faire des addslashs et ensuite vous allez supprimer ces slashs avant de montrer que les données et tout de même addslashs n'est pas aussi efficace que mysql_real_escape_string, utilisez mysql_real_escape_string si vous utilisez mysql_query comme db fonctions pour quering, ou je pense que PDO avec prepare est mieux, comme mysql_real_escape_string est spécifique à la db