Requete

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Requete

par Ryle » 15 déc. 2007, 14:05

La différence entre les deux est donnée dans la description de chacune des fonctions :
stripslashes() — Supprime les anti-slash d'une chaîne
mysql_real_escape_string() — Protège les caractères spéciaux d'une commande SQL

Je vais te donner un exemple pour essayer de t'illustrer ce qui se passe :

Dans ton formulaire tu vas saisir dans le champ "field" la valeur " L'Apostrophe "
Lorsque tu soumets le formulaire tu vas récuperer :
- si magic quotes est activé : $_POST['field'] == " L\'Apostrophe "
- si magic quotes est désactivé : $_POST['field'] == " L'Apostrophe "
Dans ta requête sql, tu vas délimiter ta chaine d'apostrophes, il te faut dont protéger les apostrophes éventuelles que contient ta chaine. Si magic quotes est activé, c'est déjà fait (mais ça ne protège pas nécessairement tous les caractères spéciaux SQL), sinon il faut le faire.

L'idée est donc de supprimer les antislashes ajoutés par magic quotes le cas échéant, pour pouvoir ensuite utiliser mysql_real_escape_string() (si tu ne vires pas les antislashes avant de l'utiliser, tu vas obtenir la chaine suivante : " L\\\'Apostrophe " dans laquelle l'antislash et l'apostrohe sont tous deux protéger d'un nouvel antislash)

Ta requête ressemblera donc à " INSERT INTO table (champ) VALUES (' L\'Apostrophe ') "
Et la valeur de "champ" dans ta base sera bien " L'Apostrophe ".

Si tu effectues un SELECT champ FROM table, tu vas bien obtenir cette valeur, dont il te faudra à nouveau protéger l'apostrophe si tu la ré-utilise dans un update ou dans une autre requête.

En résumé, quelqu'en soit sa provenance, dès que tu utilises une chaine dans une requête SQL, il faut la protéger :).

A noter par ailleurs que lorsque tes champs sont de type numérique, il ne faut pas mettre d'apostrophe autour des valeurs :
"SELECT * FROM rpg_objets WHERE id=".$id_objet;
MySQL le tolère, mais est obligé de faire des tests et des conversions pour pouvoir insérer ta chaine dans un champ de type numérique.

par supercanard » 15 déc. 2007, 12:17

Je suis un peu embrouillé. Globalement j'ai compris, enfin pas complètement l'histoire des injections. Le plus simple, sans parler encore des injections SQL, mais pour éviter l'erreur d'insertion est donc :

- On teste si les magic quote sont activées ou non
- On stripslashes

Question : Voilà un bout de code avec l'opération sur la variable test :
$id_objet= 2; // Gain Objet
$req_objet= mysql_query("SELECT * FROM rpg_objets WHERE id='".$id_objet."'"); // Gain objet
				$data_objet= mysql_fetch_array($req_objet);

				$test = mysql_escape_string($data_objet['description']);
				
				$req_inventaire= mysql_query("INSERT INTO rpg_inventaire (id,nom,type,description,bonus_pa,id_joueur) VALUES ('','".$data_objet['nom']."','".$data_objet['type']."','".$test."','".$data_objet['bonus_pa']."','".$data_joueur['id']."')") OR die('Erreur de SQL !<br>'.mysql_error());
Quel différence entre :
$test = mysql_escape_string($data_objet['description']);
et
$test = stripslashes($data_objet['description']);
?

Donc concrètement il faut faire ceci pour toutes les variables qui sortent d'une base de donnée pour y re-rentrer aussi tôt dedans puisque magic_quotes_runtime est désactivé ? :

"Echappe les données provenant d'une source externe (base de données, fichier texte etc...).
Valeur par défaut : magic_quotes_runtime est généralement désactivé par défaut."

par AB » 15 déc. 2007, 05:23

Précision
Si j'ai bien suivis gpc concerne juste les variables GET, POST
GPC ça veut dire GET POST et COOKIES

Pour faire correctement les choses il est plus simple de tester l'activation ou non des magic quotes (comme te l'a indiqué Ryle), de supprimer les anti slashes si l'option est activée puis de protéger l'insertion de tes variables dans ta base de donnée par un mysql_real_escape_string()

Une fonction pour supprimer les anti slashes si get_magic_quotes_gpc() est activé (sans incidence si get_magic_quotes_gpc() désactivé) :
function stripgpc($value) {
		
			$value = (get_magic_quotes_gpc())? stripslashes($value) : $value;
			return $value;
		}
donc finalement
$variable_post_toto_prete_pour_insertion = mysql_real_escape_string(stripgpc($_POST['toto']));

par supercanard » 15 déc. 2007, 01:58

Merci pour les infos

Je viens de regarder :
Magic_quotes_gpc ON
Magic_quotes_runtime OFF

Si j'ai bien suivis gpc concerne juste les variables GET, POST

Et runtime c'est pour les sources externes, donc ça correspond à mon problème puisque :

Je récupère les données dans une table, donc source externe
et je les renvois dans une autre table
C'est sur OFF donc pas d'antislash... J'ai juste ?

Que me conseillez vous ? D'activer ou d'utiliser les fonctions addslashes PHP ?

par Ryle » 15 déc. 2007, 01:36

Dépend de la configuration du serveur... si les magic quotes sont activées, alors php va par défaut faire un addslashes() sur toutes les variables qu'il va récupérer en POST ou en GET, sinon, ben il le fait pas et c'est à toi de le gérer pour éviter ce genre d'erreur :)

A noter qu'il est recommandé de passer toutes les chaines dont tu ne maitrise pas le contenu par la fonction mysql_real_escape_string() pour protéger les caractères spéciaux et éviter les injections sql.

En général, on testes la conf pour vérifier si les magic quotes sont actives, si oui on passe la variable dans un stripslashes() pour retirer les antislash que php a ajouté sans nous consulter, et enfin on protège la chaine pour pouvoir l'utiliser dans une requête mysql ou autre (Oracle par exemple nécessite de doubler les apostrophes et non pas de les backslasher pour les protéger) :)

par supercanard » 14 déc. 2007, 20:25

Merci pour votre aide
J'ai corrigé tout ça maintenant j'en sais effectivement plus :

Code : Tout sélectionner

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[b]action[/b].','10','1')' at line 1
Voilà ou est le problème. Avant action il y a un apostrophe dans la chaine.
Celà veut donc dire qu'il faut que je mette des addslashes et stripslahes ?
Ce que je ne comprend pas c'est qu'habituellement je ne m'en sert pas et je n'ai pas de problème... Il y a une raison ?

par Ryle » 14 déc. 2007, 19:10

Ce ne sont pas seulement les variables qu'il te faut afficher et contrôler, c'est toute la requête. C'est pourquoi on préconise de ne jamais spécifier de requête dans le mysql_query() mais de toujours utiliser une variable pour la stocker afin de pouvoir l'afficher aisément.

Par ailleurs, si ta requête d'insertion ne fonctionne pas, c'est innévitablement parce qu'il y a une erreur. S'il n'y en avait pas... ben elle fonctionnerait.
Et comme le souligne Zeus, la gestion d'erreur SQL (qui n'a rien à voir avec une erreur de code php) est indispensable si tu veux vérifier qu'un code SQL s'est déroulé sans erreur. C'est pas un truc à rajouter à l'occasion ;)

Ca te permettra nottament de savoir où regarder... est-ce le nom de la table qui est incorrect, le nombre de paramètre, le nom des champs, le format des champs, est-ce que tu n'essaye pas de mettre une valeur null dans un champ ou elle est interdite, une chaine trop grande pour un varchar, ton champ id est il en auto-incrément, n'y a-t-il pas de doublon sur la clé primaire, envoi-tu une chaine entre apostrophes alors que le champ est numérique ...

par supercanard » 14 déc. 2007, 18:57

Si tu fait un echo de ta requête et que tu essayes de l'exécuter à la main, que se passes-t-il ?

De plus, je ne vois aucune gestion d'erreur, comment peut tu être sûr qu'elle n'échoue pas ?
Rien ne se passe quand je fait un echo de la requête.
Si je remplace les variables par les valeurs directement l'enregistrement se fait.
Pourtant j'ai bien affiché avec des echo les variables, histoire de voir si elles étaient correctes...

Oui la gestion d'erreur, il faudra que je le rajoute... effectivement

par zeus » 14 déc. 2007, 18:50

Si tu fait un echo de ta requête et que tu essayes de l'exécuter à la main, que se passes-t-il ?

De plus, je ne vois aucune gestion d'erreur, comment peut tu être sûr qu'elle n'échoue pas ?

Requete

par supercanard » 14 déc. 2007, 18:35

Bonsoir,

Voilà j'ai une requête qui fonctionne sans fonctionner. Pas d'erreur mais en revanche rien ne s'insert dans ma base :
$req_inventaire= mysql_query(
"INSERT INTO rpg_inventaire (id,nom,type,description,bonus_pa,id_joueur)
VALUES ('','".$data_objet['nom']."','".$data_objet['type']."','".$data_objet['description']."','".$data_objet['bonus_pa']."','".$data_joueur['id']."')");
Ce que j'insère proviens d'une autre requête. J'ai bien vérifier avec des echo si il n'y avait pas de problème, c'est ok de ce coté.

Erreur de syntaxe ? :?