XSS dans requete sql un peu spéciale

[Résolu]
Signaler
Messages postés
55
Date d'inscription
mardi 15 février 2005
Statut
Membre
Dernière intervention
4 juin 2010
-
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
-
Bonjour à tous et toutes,
J'ai une question concernant les requete mysql et la sécurité relative au injections sql.

(cette requete est utilisé que pour une interface de gestion administrateur mais j'aimerais qu'elle soit quand meme clean au niveau des injections sql (des fois que le chat de l'admin ait l'habitude de marcher sur le clavier))

j'ai un formulaire avec 4 champs correspondant respectivements au nom de 2 tables mysql et de 1 colonne de chaque table (soit 2 colonnes) et je souhaite construire une requete (SELECT) qui sera constituer des variables saisies par l'admin (exemple : 'SELECT '. $champs_table_1.' FROM `'.$nom_table_1.'`')

Je compte utiliser la fonction mysql_real_escape_string() pour chaque variable saisie par l'utilisateur mais cette écriture change par rapport a ce que j'avais l'habitude de faire à savoir : 'SELECT champ1 FROM `table1`WHERE champ1=\''.$variable_saisie_par_user.'\''. Je me demandais donc si il pouvait y avoir un souci de sécurité lorsque le nom du champs a selectionner ou le nom de la table etais directement rentré par l'utilisateur (ici je parle d'un souci de securité au niveau XSS)

2 ieme question : Est il possible avec mysql d'effectuer une meme requete pour plusieurs tables (par exemple : 'SELECT '.$champs_table_1.' FROM `table1`,`table2`) je pense que ce n'est pas possible mais je voulais une confirmation de la part de quelqu'un de plus experimenté que moi.

Merci d'avance pour vos réponses sur le sujet.

mickadevelop

3 réponses

Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
18
Si tu laisses l'utilisateur la possibilité de saisir directement une partie de la requête,alors oui, il y a une faille.
C'est pour cela qu'il existe des DBA (DataBase Administrator) qui sont payés rubis sur l'ongle pour gérer les droits de chaque utilisateur sur telle ou telle table.
Et c'est pour leur faciliter le travail que les moteurs de bases de données permettent de créer des vues (tout est dans la doc de mysql).

Plus concrètement, pour ton problème, tu as plusieurs solutions. Probablement aucune n'est miraculeuse...

Au lieu d'utiliser des champs textes, utiliser des listes déroulantes. Mais ça ne fait pas tout, puisqu'un formulaire peut être construit manuellement... Alors il faut vérifier avant la construction de la requête si les tables correspondent aux tables auquel on souhaite laisser l'accès.

On peut aussi parser la requête construite avant de l'exécuter pour en extraire les tables et tester les droits. Mais c'est bourrin et lourd...

Une autre solution est d'avoir plusieurs comptes utilisateurs sur la base de données, et de définir des droits très stricts pour chacun. On pourra alors utiliser l'un ou l'autre, suivant l'utilisateur connecté, pour effectuer les opérations. Si un utilisateur triche et tente d'accéder à une table qui lui est interdite, la requête échouera avec une erreur 1227 : Access denied; you need the xxxxxxx privilege for this operation, erreur qui peut être interceptée pour afficher un joli message d'erreur pour l'utilisateur.

La dernière solution que j'ai dans mon chapeau consiste à avoir confiance en son admin, à faire valider la requête construite avant validation, à veiller à ce que l'admin soit compétent, etc... Mais personne n'est infaillible, et même avec de la bonne volonté, on peut tout casser...
Messages postés
2483
Date d'inscription
jeudi 30 novembre 2006
Statut
Membre
Dernière intervention
14 janvier 2011
18
Salut,

D'une manière générale, il faut TOUJOURS protéger avec mysql_real_escape_string les données textes que l'on insère dans une base de données et qui proviennent d'une source externe (autre base de données, fichier, variables POST ou GET, etc).
TOUJOURS.
Sans ça, c'est systématiquement la porte ouverte à une faille XSS.

Pour les autres types de données, c'est moins sensible, puisque par exemple, les valeurs numériques n'ont pas besoin d'être entourées de guillemets dans la requete.
On peut s'assurer que les données numériques que l'on traite sont bien des nombres (intval(), transtypage avec (int) etc).

Pour ta deuxième question, oui, c'est tout à fait possible. Ca s'appelle une jointure.
La syntaxe la plus courante est proche de ce que tu as écris :

SELECT a.champ1, b.champA FROM tableA AS a, tableB AS b WHERE bidule='machin';

Des jointures plus complexes peuvent être faites, selon les résultats que l'on veut obtenir. On peut filtrer, grouper, trier, etc.

Pourquoi ne pas lire la doc de MySQL ?
http://dev.mysql.com/doc/refman/5.0/fr/join.html
Messages postés
55
Date d'inscription
mardi 15 février 2005
Statut
Membre
Dernière intervention
4 juin 2010

Coucou neigedhiver,

tu viens de me refroidir en boulersant mon idée de départ sur l'impossibilité d'effectuer une requete pour plusieurs tables.
Non en réalité je te remercie pour la jointure du tuyau euh .... non le tuyau de la jointure.

desoler une journée devant un pc ca laisse des traces...

Pour parler plus sérieusement je ne suis pas rentrer dans les details des requetes utilisant la jointure mais en regardant de loin et en me focalisant plus sur les problemes d'injections, meme en utilisant la fonction mysql_real_escape_string() il serait envisageable de faire une injection sql dans la partie definissant les champs et les tables pour modifier la requete et tirer des info dont on ne voulais pas donner l'acces.

exemple : on rentre la variable $GET['variablesaisieparutilisateur']='tableb as b, tablec as c';

la requete va devenir :

SELECT a.champ1, b.champA FROM tableA as a, tableb as b, tablec as c WHERE ...

voila j'espere avoir ete clair dans ma pose du probleme et espere avoir votre avis sur la question et savoir si ce represente un reel risque et faut il effectuer un filtrage des variables lors de la saisie.
merci

mickadevelop