[Résolvé][PHP]Message d'erreur que je comprend pas - First argument should be an array

Bonjour à toutes zé à tous,

j’ai un message d’erreur je sais pas pourquoi :blonde: :smiley:

Warning: extract(): First argument should be an array in 'emplacement' on line 65

Voici mon code :

      	$req = "SELECT *FROM cachettes WHERE titre = '$typecachette' ";
      	$res = mysql_query($req)
        	or die ("Tu t'es gourré dans ta requête pov' tache !");
      	$ligne = mysql_fetch_array($res, MYSQL_ASSOC);
      	$typecachette = ucfirst($typecachette);
      	extract($ligne);
      	echo	"	<center>
          	<table style='position:absolute; top:-220px; left:18px' cellspacing='0' border='1'>
            	<tr align='center'>\n
            	<td align='center'>
              Désignation
            	</td>
            	<td align='center' width=400>
              $typecachette
            	</td>\n
            	</tr>
            	<tr align='center'>
            	<td align='center' height=150>
              Descriptif
            	</td>
            	<td align='center' width=400>
              $descriptif
            	</td>\n
            	</tr>
            	<tr align='center'>
            	<td align='center'>
              Prix Public
            	</td>
            	<td align='center' width=400>
              $prix €
            	</tdn
            	</tr>
          	</table>
          </center>";

l’erreur indique que c’est au niveau de “extract($ligne);” qu’il y a 1 problème, mais je sais pas quel est le problème, donc encore moins le résoudre …

Y’a des avis là-dessus ?

:jap: par avance

Facile : le tableau que tu passe à la fonction n’est pas un tableau.

cela signifie que tu n’as aucun enregistrement.

Au passage, il y a une potentielle injection SQL dans ton code.

Donc je dois créer 1 tableau au départ ? :blonde:

y’a quoi comme potentielle injection ? :blonde:

désolé j’suis un peu beaucoup débutant …

Je sais pas si c’est de ça que parlait Sans-Nom, mais dans ta requete :
$req = "SELECT *FROM cachettes WHERE titre = ‘$typecachette’ ";
Si $typecachette contient une simple quote ’ ta requête ne vas pas fonctionner car ton champ est délimité par des simples quotes

Ex :
$typecachette = “L’autre”;

$req = "SELECT *FROM cachettes WHERE titre = ‘$typecachette’ ";
Quand ça va être interprété, ça va prendre pour valeur :

SELECT *FROM cachettes WHERE titre = ‘L’autre’
Il va donc croire que titre doit être égale à “L”, et ne vas pas comprendre le bout de code qui reste…

De plus, il est préférable d’utiliser mysql_fetch_assoc, c’est plus cours dans ton cas.

Sinon extract sert pour séparer un tableau, du genre :
$table=array('champs1" => ‘value1’,
'champs2" => ‘value2’,
'champs3" => ‘value3’);

extract($table); va séparer ton tableau en prenant pour nom de variable les clés de ton tableau, ici :
$champs1=‘value1’;

Ton erreur signifie seulement que la variable que tu passes dans extract n’est pas un tableau mais une simple chaîne.

A toi d’y remédier.

En fait j’utilise mysql_fetch_array qui retourne un tableau qui contient la ligne demandée dans le résultat result et déplace le pointeur de données interne d’un cran.

donc la variable $ligne sera 1 tableau je me trompe ?
Ensuite j’utilise la fonction extract pour extraire et séparer chaque variable contenue dans le tableau et les afficher séparément dans 1 tableau …

J’ai faux ou bien ?

Ecoute le plus simple à faire pour vérifier de quel est type et une variable et qu’est-ce qu’elle contient est d’utiliser var_dump();

Fais un var_dump($ligne); avant ton extract, et viens poster ce qu’il t’affiche.

:oui: … mais pour bien mettre en évidence la faille de sécurité en évidence, supposons que $typecachette = “1’; DELETE FROM cachettes;#”

bah ça va faire que le serveur SQL va :

  • faire une requète SELECT
  • effacer toute ta table sans confirmation
  • sortir normalement

pour parer à ça, la solution consiste à bien filtrer tes inputs utilisateurs (ne JAMAIS faire confiance à ce que l’utilisateur saisis) et utiliser mysql_real_escape_string() sur chacun des arguments que tu passes à une requète SQL …

après, tu peux pousser plus avant et limiter tes requètes, voir créer une compte spécifique qui ne peut faire que des SELECT dans mySQL :jap: …

sinon pour ton problème de tableau, comme l’as dis l’homme sans-nom, à 99.9%, c’est que ta requète n’as retourner aucune résultat …

à ta place, je rajouterais un :


$res = mysql_query($req)
        or die ("Tu t'es gourré dans ta requête pov' tache !");
if ( mysql_num_rows($res) <= 0 )
{
  ?>Pas de résultat, c'est bateau hein ?<?php
}
else
{
      $ligne = mysql_fetch_array($res, MYSQL_ASSOC);
     ....
     </center>';
}

ça me sort ceci :

boolean

:ko:

le seul résultat boolean pour mysql_fetch_array est FALSE, qui est retourner quand il n’y a plus de lignes … donc c’est bien ce qu’on disait : ta requète ne retourne aucune ligne (est-ce que tu l’as tester sur ton serveur SQL au moins ? avec une valeur pour $typecachette qui contient des enregistrements ?) :sarcastic:

A ouai carrément :o ! Ca j’savais po, mais si nos variables ne sont pas définies par un user, y a pas de crainte ^o) ? Moi j’utilisais un simple AddSlashes… :confused:

Ca veux dire qu’il ne retourne aucun résultat…

[mode parano]
y’a toujours une crainte :o …
[/mode parano]
allez, bonne lecture : http://www.phpsecure.info/v2/article/InjSql.php :super:
(normalement après, tu devrais relire tout le code que tu as écrit depuis la nuit des temps :paf:)

je dirais même plus : ça ne retourne aucune résultat :o

[:shy]

:ane:

Ce message n’était pas conforme aux règles d’utilisation du nouveau forum :

JE TE HAIS :’( !

je sais, je suis passé par là aussi, j’ai eu la même réaction envers le mec qui m’avait filé le lien … bon courage, je compatis :jap:
(mais je ne t’aiderais pas à sécuriser ton code, démerdes-toi :paf:)

Je ne t’aurais pas demandé d’aide, sinon tu saurais comment je procède et tu aurais la clé de mon codage :stuck_out_tongue: !

la règle de base > “Security through obscurity is no security at all.” :jap:

Je sais, c’est la base du hacking (dans le sens premier et noble du terme). M’enfin si on a confiance en soi, no prob’ :^^ !

Sinon crougnagna tu as trouvé ton problème ?

(C’est bien jolie de squatter le sujet des autres mais faut avant tout qu’il n’ait plus d’interêt car résolu :confused: )

En fait, l’utilisateur ne pourra pas renvoyer la variable qu’il veut puisque la variable $typecroquette sera envoyé par un fichier flash … J’ai juste ou bien ? :blonde:
En gros j’ai un menu en flash, l’utilisateur clique sur une partie du menu qui va envoyer la variable avec 1 certaine valeur à mon fichier php.

en fait ça me sort cette erreur 1 seule fois, quand la page est chargée. Une fois que la variable $typeccachette a une valeur (donc quand j’ai cliqué sur 1 partie de mon menu), le message d’erreur disparait …

pas forcèment, car ton fichier flash va appeller ton fichier PHP via une requète HTTP (du moins à mon époque ça fonctionnait comme ça) … il est assez facile de récupérer le code AS d’un fichier flash, donc de trouver l’URL d’appel de ton fichier PHP, et donc de pêter ta base …

maintenant, la solution qu’on propose (rajouter UN appel de fonction déjà toute faite) est simplisme au possible … même modifier la configuration PHP via le php.ini serait plus compliqué que ça … donc, pourquoi dire “de toute façon ça n’arriveras jamais” plutôt que faire un copier-coller du code exemple (5 secondes montre en main) et être certain d’être protégé de ce type d’attaque ? :neutre:

'fin je sais pas, mes profs m’ont tellement bassiné durant mes études sur “sécurité, toujours sécurité, et encore sécurité” que je ne me pose même plus la question :paf:

bah c’est logique … si ta variable n’as pas de valeur, ton programme va exécuter cette requête :
SELECT *FROM cachettes WHERE titre = ‘’;

qui visiblement ne retournes aucun résultat … ce qui peut être tout à fait normal, ce n’est pas un bug … le bug, c’est que la suite de ton programme ne gère pas le cas où il n’y a aucun résultat retourné > d’où le test pour continuer l’exécution du code s’il y’a au moins 1 résultat retourné :oui:

ce que je disais un peu plus haut en fait, avec même un bout de code à copier-coller :super: …

(je voudrais pas devenir méchant comme Sans-Nom, mais je ne suis pas prof, donc je n’aime pas me répéter :o :sarcastic: :paf:)

Bon j’ai résolu mon petit problème en insérant juste ceci :

if ($typecroquette <> "") //modification
      	{
        extract($ligne);
        echo	"	<center>
          	...</center>";

comme ça, la fonction extract ne s’appliquera que si la variable n’est pas vide, donc n’est pas une variable boolean :smiley:

Par contre je n’ai pas vu de bout de code pour palier à ma faille de sécurité (veuillez pardonner ma blondure), et j’viens de réaliser le problème d’où ma prochaine question : comment faire pour qu’un utilisateur puisse juste accéder à la commande SELECT ?

Tu n’as pas forcément de solutions viables. J’ai pas tout suivi, mais si tu veux qu’il puisse faire genre :

SELECT * FROM a WHERE id = 5

Tu peux déjà chercher si la première instruction c’est SELECT, UPDATE, ou DELETE, etc.

Le SQL est assez basique :

(SELECT * FROM a WHERE id = 5)

A peu de chances de fonctionner (pas comme : <?php (f()); ?>).

Donc, tu peux commencer par faire un ltrim, supprimer les commentaires (/* et /, --.$), et vérifier si le premier mot c’est bien SELECT (une petite regexp : /^SELECT\s+/).

Si tu es plus parano, tu crée un pseudo langage que tu pourras traduire en SQL.

Sinon pour les injections SQL, tu n’en as plus quand tu utilises que des requêtes préparées :slight_smile: Et même si tu n’en as pas, tu peux faire un wrapper te le faisant pour toi.

Il reste juste à faire attention aux requêtes faîtes maison, mais bref.