2010-09-08 7 views
2

Peut-être que je n'ai pas encore assez de compréhension de cela, alors je cherche un peu de direction.Problème de sécurité/injection SQL avec collation mysql?

Tous nos tableaux montrent une collation de latin1_swedish_ci. Voici ce que je vois dans les variables de mysql:

collation connection utf8_general_ci 
(Global value) latin1_swedish_ci 
collation database latin1_swedish_ci 
collation server latin1_swedish_ci 

Maintenant, nous voyons UTF8 (ou, au moins, contenu langue étrangère) stockés dans la db assez souvent, et il rend correctement. Est-ce que la collation n'a pas d'importance pour ça?

Utiliser quelque chose comme php addslashes() sur l'entrée de l'utilisateur - est-ce suffisant? Ou est-ce que cela laisse une opportunité d'injection?

EDIT: Alors, en regardant l'ensemble des paramètres collation/charset, au moins dans phpmyadmin, je vois:

character set client utf8 
(Global value) latin1 
character set connection utf8 
(Global value) latin1 
character set database latin1 
character set filesystem binary 
character set results utf8 
(Global value) latin1 
character set server latin1 
character set system utf8 
character sets dir /usr/share/mysql/charsets/ 
collation connection utf8_general_ci 
(Global value) latin1_swedish_ci 
collation database latin1_swedish_ci 
collation server latin1_swedish_ci 
+0

ces paramètres ne signifie rien. ils sont tous remplacés. ce sont juste des valeurs par défaut. Vérifiez les tableaux particuliers charset. La requête SHOW CREATE TABLE peut l'afficher –

+0

L'exécution de "show create table" sur nos différentes tables montre le jeu de caractères par défaut = latin1. Du côté php, nous définissons le type de contenu en sortie sur utf-8. Donc, il peut y avoir une discordance ici, mais les choses s'affichent correctement. . . – Neil

Répondre

2

Le collation ne décrit que des règles pour comparer les caractères d'un certain jeu de caractères. Une règle pourrait être que a est égal A, b est égal B, etc. ou que ß est égal à ss, ä est égal à ae, etc.

Et pour une Escaping explicite de chaînes pour MySQL, utilisez mysql_real_escape_string. Cette fonction est contraire à addslashes et mysql_escape_string prend en compte le codage de caractères réel de la connexion.

Mais vous devez définir le codage de caractères de la connexion avec mysql_set_charset. Parce que sinon un changement ne sera pas reconnu (voir C API Functions Description – mysql_real_escape_string()):

Si vous avez besoin de changer le jeu de caractères de la connexion, vous devez utiliser la fonction mysql_set_character_set() plutôt que d'exécuter une instruction SET NAMES (ou SET CHARACTER SET). mysql_set_character_set() fonctionne comme SET NAMES mais affecte également le jeu de caractères utilisé par mysql_real_escape_string(), ce qui n'est pas le cas pour SET NAMES.

+0

+1 c'est la bonne réponse. bien que adodb et pdo utilisent mysql_escape_string() et tout le monde aime les requêtes paramétrées ... – rook

+1

mysql_real_escape_string fait son travail spécial seulement si mysql_set_charset() est utilisé. sinon, il agira comme mysql_escape_string –

+0

@Col. Shrapnel: Je ne le savais pas. Mais vous avez raison, voir http://dev.mysql.com/doc/refman/5.0/en/mysql-real-escape-string.html. – Gumbo

0

Toutes nos tables montrent une collation latin1_swedish_ci
contenu en langue étrangère rend correctement

Il y a quelque chose de mal avec votre base de données.
Il sera soit incapable de stocker des caractères non-latin ou incapable de commander/filtrer le contenu de la base de données correctement.

Pour stocker des caractères étrangers, le jeu de caractères utf8 doit être défini pour les tables. Ainsi que le jeu de caractères de connexion. Utiliser quelque chose comme php addslashes() sur l'entrée de l'utilisateur - est-ce suffisant? Addslashes est suffisant, si vos charsets latin1 et utf8 seulement. Mais le reste est faux.Addslashes() ou toute autre fonction d'échappement n'aident pas tout seul!

  1. Cela fonctionne uniquement avec des guillemets autour des données échappées. Ainsi, il ne devrait pas être juste "Utilisation de quelque chose comme addslashes()" mais "Utilisation de quelque chose comme addslashes() pour les chaînes entre guillemets et type pour les numéros"
  2. Pas pour la saisie utilisateur! S'échapper n'est pas pour désinfecter! C'est juste pour le formatage correct de la requête. Toute requête. Avec n'importe quelles données. Non seulement l'entrée de l'utilisateur, comme tout le monde dans ce monde pauvre pense, mais pour toutes les données (qui va à la requête en tant que chaînes entre guillemets).
+0

Merci pour les commentaires. J'ai inclus mes paramètres complets de jeu de caractères/classement ci-dessus, je ne suis pas sûr de ce qui est incorrect. En outre, je ne suis pas sûr de ce que seraient les paramètres de mes processus php, je verrai si je peux comprendre cela. – Neil