[PHP] Remplissage Dropdown

Bonjour à tous,

Tout d'abord, je commence tout juste dans le développement web, je m'excuse par avance pour mes approximations, méconnaissances et autres abus de langages. N'hésitez pas à me reprendre

Voici la partie de mon code qui me pose problème :

<?php

if(isset($_POST['btn_view'])) 
{

  $id = $_POST['btn_view']; 

  $name = $_POST['name' . $id];
  $customer = $_POST['customer'. $id];
  $number = $_POST['number'. $id];
  $state = $_POST['state'. $id];

  $_SESSION["affair_id"] = $id;
  $_SESSION["affair_name"] = $name;
  $_SESSION["affair_customer"] = $customer;
  $_SESSION["affair_number"] = $number;
  $_SESSION["affair_state"] = $state;

  header("Location: affair/affair.php");
}

echo '
<div class="dropright">
<img data-toggle="dropdown" src="./images/menu.png">
<div class="dropdown-menu">
<a class="dropdown-item" href="menu.php">Menu</a>';

$db = Database::connect();
$statement = $db->query('SELECT affair.id, affair.name, affair.customer, affair.number, affair.state, users_task.user AS user FROM affair INNER JOIN users_task ON users_task.affair = affair.id ORDER BY affair.id DESC');

while($item = $statement->fetch()) 
{
    if($item['user']==$_SESSION["id"])
    {

        echo '
        <form id="liste_header" action="header_left.php" role="form" method="post" enctype="multipart/form-data">

            <input name="id'. $item['id'] . '" type="hidden" value="'. $item['id'] . '">
            <input name="name'. $item['id'] . '" type="hidden" value="'. $item['name'] . '">
            <input name="customer'. $item['id'] . '" type="hidden" value="'. $item['customer'] . '">
            <input name="number'. $item['id'] . '" type="hidden" value="'. $item['number'] . '">
            <input name="state'. $item['id'] . '" type="hidden" value="'. $item['state'] . '">
            <button name="btn_view" value="'. $item['id'] . '" type="submit" class="dropdown-item" >'. $item['name'] .'</button>

        </form>
        ';
    }

}
echo '</div>
</div>  
';
Database::disconnect();
?>

Il permet de remplir une dropdown en fonction d'une base de donnée MySQL. Cette partie fonctionne très bien.

Là où ça se gatte, c'est quand je clique sur un des choix de la dropdown, cela m'envoie bien sur la page demandée mais avec les données de la mauvaise ligne de la table...

Je ne comprends pas pourquoi ça ne fonctionne pas car j'ai déjà réalisé une programmation similaire à la seule différence que ce n'était pas avec une dropdown...

Si quelqu'un voit l'erreur que j'ai faite ce serait cool

En tout cas merci d'avance à ceux qui prendront du temps à mon sujet

A plus tard j'espère

Sam

Bonjour Sam,

Quelques remarques en observant ton code :

  $id = $_POST['btn_view']; 

  $name = $_POST['name' . $id];
  $customer = $_POST['customer'. $id];
  $number = $_POST['number'. $id];
  $state = $_POST['state'. $id];

  $_SESSION["affair_id"] = $id;
  $_SESSION["affair_name"] = $name;
  $_SESSION["affair_customer"] = $customer;
  $_SESSION["affair_number"] = $number;
  $_SESSION["affair_state"] = $state;

Attention, il ne faut jamais faire confiance aux données renvoyées par des utilisateurs (voir par exemple

et vérifier la validité des données)

if($item['user']==$_SESSION["id"])

Si tu n'as besoin que des données d'un seul user, ajoute plutôt une clause WHERE pour éviter de récupérer les données de tous les utilisateurs (utilise une requête préparée).


Pour le reste j'ai un peu de mal à comprendre le format ta liste et pourquoi tu cherches à afficher toutes les données à l'avance dans ta liste ...

Si je devais faire une liste déroulante de choix, je ferais comme ceci :

<select name="ma_liste">
    <option value="id_du_choix">Le choix</option>
    <option value="id_du_choix">Le choix</option>
    <option value="id_du_choix">Le choix</option>
    <option value="id_du_choix">Le choix</option>
</select>

Une liste simple avec juste l'ID de la ligne, puis à la page suivante tu récupères les données de la ligne de l'ID choisi.

D'ailleurs, à moins que tu sois le seul utilisateur de ton outil, ça ne sert à rien d'entrer les données à l'avance dans le formulaire car il faudra de toute façon revérifier un minimum la validité de ces données à la page suivante (car il est très simple de changer les données d'un formulaire), donc autant récupérer des données fiables provenant de ta base de données directement à la page suivante (vérifie tout de même la validité de l'ID renvoyé).

Bon courage

Cordialement,

Bonsoir Sébastien,

Tout d'abord, merci pour ta réponse

Concernant ceci :

Attention, il ne faut jamais faire confiance aux données renvoyées par des utilisateurs (voir par exemple htmlspecialchars et vérifier la validité des données)

ces données ont été traitées au moment d'être rentrées dans ma base par cette fonction :

function checkInput($data) 
  {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
  } 

Là, je ne fais que réutiliser ces données. Elles ne sont pas retouchées par les utilisateurs.

Ici, mon formulaire me sert à insérer des noms d'affaires, qui ont été préalablement rentrées par un utilisateur dans une page dédiée, dans ma liste déroulante en leur affectant leur ID et la fonction submit, pour que lorsque l'on clique dessus, on accède à la page "affair.php" qui affiche les données de l'affaire sur laquelle on a cliqué...

Je n'utilise peut être pas la bonne logique...

Il y a sûrement mieux à faire ?

Ici, mon formulaire me sert à insérer des noms d'affaires, qui ont été préalablement rentrées par un utilisateur dans une page dédiée, dans ma liste déroulante en leur affectant leur ID et la fonction submit, pour que lorsque l'on clique dessus, on accède à la page "affair.php" qui affiche les données de l'affaire sur laquelle on a cliqué...

Je ne suis pas sûr d'avoir bien tout compris mais je vais quand même essayer de te répondre

Là, je ne fais que réutiliser ces données. Elles ne sont pas retouchées par les utilisateurs.

Même si les données de ta base de données sont parfaitement fiables, le risque n'est pas là ...

Par exemple, si tu utilises ces données directement pour afficher les données d'une affaire :

  $id = $_POST['btn_view']; 

  $name = $_POST['name' . $id];
  $customer = $_POST['customer'. $id];
  $number = $_POST['number'. $id];
  $state = $_POST['state'. $id];

  $_SESSION["affair_id"] = $id;
  $_SESSION["affair_name"] = $name;
  $_SESSION["affair_customer"] = $customer;
  $_SESSION["affair_number"] = $number;
  $_SESSION["affair_state"] = $state;

Si tu ne fais aucun contrôle d'aucune sorte avant d'afficher les données d'une affaire, cela revient à créer une faille importante permettant d'afficher potentiellement n'importe quelle affaire, car il est très simple de modifier les informations de ton formulaire et de changer les ID (en faisant par exemple un simple clic droit sur ton formulaire, inspecter et tu modifies le code HTML).

Pire encore, si tu utilises l'une des valeurs $_POST dans une requête SQL (non préparée), tu mets potentiellement ta base de données en danger (voir

pour mieux comprendre).

Il y a sûrement mieux à faire ?

Une possibilité :

Page 1 :

  • tu crées ton formulaire avec la liste de choix d'ID que l'utilisateur peut afficher (le but est de renvoyer l'ID en page 2 et rien d'autre)

Page 2 :

  • tu vérifies que l'utilisateur est toujours connecté
  • tu vérifies la validité de l'ID (par exemple si c'est un entier, ou au moins faire un htmlspecialchars)
  • tu vérifies aussi si cet utilisateur a le droit d'afficher les informations de l'affaire demandée (car rappelle-toi qu'il est facile de changer les données dans un formulaire)
  • et enfin, tu affiches les données demandées

Page 2 = affair.php (inutile de renvoyer sur une page intermédiaire pour rediriger ensuite sur affair.php, affair.php peut très bien recevoir les données $_POST)

J'espère que ça t'aidera un peu et t'évitera quelques mauvaises surprises (failles exploitées)

Si tu ne fais aucun contrôle d'aucune sorte avant d'afficher les données d'une affaire, cela revient à créer une faille importante permettant d'afficher potentiellement n'importe quelle affaire, car il est très simple de modifier les informations de ton formulaire et de changer les ID (en faisant par exemple un simple clic droit sur ton formulaire, inspecter et tu modifies le code HTML).

Pire encore, si tu utilises l'une des valeurs $_POST dans une requête SQL (non préparée), tu mets potentiellement ta base de données en danger (voir injection SQL pour mieux comprendre).

Ah d'accord je n'avais pas du tout cette notion

Du coup, j'ai fait avec des liens <a> :

<?php

echo '
<div class="dropright">
<img data-toggle="dropdown" src="./images/menu.png">
<div class="dropdown-menu">
<a class="dropdown-item" href="menu.php">Menu</a>';

$db = Database::connect();
$statement = $db->query('SELECT affair.id, affair.name, affair.customer, affair.number, affair.state, users_task.user AS user FROM affair INNER JOIN users_task ON users_task.affair = affair.id ORDER BY affair.id DESC');

while($item = $statement->fetch()) 
{
    if($item['user']==$_SESSION["id"])
    {

        echo '
            <a class="dropdown-item" href="./affair/affair.php?id_affair='. $item['id'] . '">'. $item['name'] .'</a> 
        ';
    }

}
echo '</div>
</div>  
';
Database::disconnect();
?>

C'est mieux ou pas ? Point de vue sécurité ? En tout cas comme ça ça marche comme je le souhaite ^^

Oui ça te simplifie grandement le code avec les liens

Mais contrôle quand même bien la validité de l'id $_GET['id_affair'] et si l'utilisateur a le droit d'afficher les données de cet ID car le risque est le même que pour la version $_POST.

Du genre, je déconnecte la personne si elle accède, en modifiant l'id dans l'url, à une affaire qu'elle n'a pas le droit c'est ça ?

Du genre, je déconnecte la personne si elle accède, en modifiant l'id dans l'url, à une affaire qu'elle n'a pas le droit c'est ça ?

Pas forcément déconnecter mais c'est toi qui vois

Pour ma part dans un cas comme ça je retourne généralement une page d'erreur 404.

Ah d'accord

Merci en tout cas

je vois que vous n'avez pas protégé vos entrées pour que votre projet soit risqué

Bonsoir tracikeel52,

Merci pour ton message :

je vois que vous n'avez pas protégé vos entrées pour que votre projet soit risqué

Je débute, peux-tu préciser et me donner un exemple avec le dernier bout de code que j'ai mis ?

Je te remercie,

A plus tard

Sam

Comme cette input

Non protégé

  $name = $_POST['name' . $id];

protégé

$name = mysql_real_escape_string($_POST['name' . $id]);

J'avais fait une fonction pour "sécuriser" :

function checkInput($data) 
  {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
  } 

J'imagine que ça ne suffit pas. Je le rajoute à la suite comme ceci ?

function checkInput($data) 
  {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    $data = mysql_real_escape_string($data);
    return $data;
  } 

Oui, c'est mieux qu'avant. Toutes vos entrées sont désormais securiser contre les vulnérabilités sql injection

Ok super je rectifie mon code ! Merci !

Rechercher des sujets similaires à "php remplissage dropdown"