Page 1 sur 3
Faille de sécurité facture dans phpmyshop
Posté : 11 août 2005, 21:36
par stanthecop
Bonjour,
J'ai installé phpmyshop, script e-commerce simple mais plutôt bien fait.
Il y a une faille importante tout de même et je n'arrive pas à m'en sortir.
Lors de l'édition de la facture, à la fin du processus de commande, celà ouvre une nouvelle page que le client peut imprimer et renvoyer avec son réglement.
Seulement voilà, l'adresse de la page se termine par quelquechose du genre "facture.php?facture2" "2" correspondant au n° de commande. Or, dans le navigateur, si je change ce numéro, j'accède sans problèmes aux commandes des autres clients...
Si quelqu'un utilise ce script et a réussi à enlever cette faille, je le remercie d'avance de bien vouloir éclairer ma lanterne...
PS : J'ai fait (oh le vilain) des tests sur des sites utilisant phpmyshop, et effectivement, en changeant le n° id de facture dans la barre d'adresse, j'ai accès à toutes les commandes passées....
Posté : 11 août 2005, 21:41
par Cyrano
Je n'ai jamais exploré ce script, mais pour éviter ce défaut, il faudrait lorsque le client s'identifie récupérer dans une variable de session les numéros de facture qui lui correspondent et ceux-la seulement: lorsqu'il essaye d'accéder à une autre facture, il faut alors vérifier que la facture demandée correspond bien au client en cours en cherchant le numéro demandé dans la variable de session définie lors de la connexion du client. Si on ne la trouve pas, on jette l'internaute vers une page par défaut.
Posté : 11 août 2005, 21:41
par stanthecop
j'ajoute que sur le site comscripts, d'où vient ce script, un utilisateur dit ceci :
Salut,
J'ai remarqué une petite faille lors de l'affichage du bon de commande. En fait, il suffit de changer le numéro du bon de commande dans la barre d'adresse pour avoir accès à tous les autres bon de commande effectué.
J'ai donc séparé (donc, nouvelle page) le bon de commande de la facture et ajouté le ligne suivante au dessus du bon de commande :
session_start();
if ( !session_is_registered("achat"))
{
header("location:index.php");
}
L'impression du document ne sera possible qu'après le commande effective. Si la session est perdue, il sera impossible d'afficher le bon de commande
Voilà, voilà...
Mais je n'ai pas compris comment faire cette manipulation...
Merci d'avance
Stan
Posté : 11 août 2005, 21:44
par stanthecop
Ton idée n'est pas mauvaise.. mais lors de mes tests de sites utilisant phpmyshop, je n'ai absolument pas dû m'identifier ni quoi que ce soit, j'ai juste tapé l'adresse dans la barre du navigateur, et changé le n° id des factures, et j'ai eu accès à tous les clients...
Posté : 11 août 2005, 22:02
par Cyrano

n'importe qui peut accéder à n'importe quelle facture sans identification ???
Posté : 11 août 2005, 22:09
par stanthecop
et bien j'ai bien peur que oui... vu que c'est bien le test que j'ai fait pour en avoir le coeur net..
par exemple, sur une adresse du style monsite.com/phpmyshop/facture.php?facture12 , il suffit de changer le n° de la fin pour tomber sur une autre facture..
J'ai fait une recherche dans Google sur phpmyshop, là on trouve des sites utilisant ce script, avec l'architecture des dossiers idem, et don, en fouillant un peu et en modifiant l'adresse, je suis tombé sur des tas de factures, avec les coordonnées clients etc etc... l'id de la facture fait juste appel à la base de données, donc les données sont justes lues...
Que penses-tu de l'astuce que j'ai citée plus haut, venant d'un utilisateur de ce script qui avait repéré la faille ?
En revanche, grand débutant, je ne vois pas comment mettre en place sa solution dans casser tout le script, je ne suis pas assez aguerri pour faire cette manip et tout laisser dans le bon ordre...
Si tu avais quelques minutes, pourrais-tu jeter un coup d'oeil à ce script ?
Merci
Stan
Posté : 11 août 2005, 22:48
par Cyrano
Personnellement, j'intègrerais une identification obligatoire: de toutes façon un client est bien obligé à un moment donné de donner ses coordonnées pour recevoir la marchandise : ça ne coute rien de lui attribuer un compte et de lui faire choisir un mot de passe. Comme ça, il s'identifie et tu vérifies.
Enfin bon, j'ai jamais utilisé de script de e-commerce tout fait, j'en ai fait un complètement maison pour une petite boite et je te garantis que personne n'accède à rien s'il ne montre pas patte blanche. Et ce n'est pas très complexe. Mais je t'accorde que reprendre un script tout fait pour le sécuriser un peu, c'est galère.
Posté : 12 août 2005, 08:38
par stanthecop
Cyrano, il y a déjà dans le script d'origine une identification, le client doit s'identifier pour pouvoir passer commande. Mais celà ne suffit apparemment pas niveau sécurité, au vu de la faille dont nous avons parlé hier.
J'ai pensé à une solution cette nuit, mais je ne sais pas si c'est techniquement faisable. L'idée en gros est la suivante, une fois que la facture est créée ( pour le client en cours qui passe sa commande sur le site ), on déplace la facture dans un répertoire protégé par un htaccess, et ainsi, impossible d'y accéder en tapant l'adresse dans le navigateur.
Mais je ne suis pas sûr que ce soit envisageable car la facture n'existe pas "physiquement" sous forme de fichier, mais est reliée aux tables de la base de données.
Deuxième idée, mais qui demanderait de modifier le script : actuellement, le bon de commande ou facture s'affiche dans une page html, avec une adresse contenant l'id de la facture. La faille est donc là, en modifiant le n0 de facture dans la barre du navigateur, on a accès aux factures des autres... Et si la facture, via un script, était éditée au format pdf, elle serait visualisable par le client ( qui pourrait l'imprimer ) ,et elle serait déplacée sur le serveur du site dans un répertoire protégée..
Cette solution te semble-t-elle possible ?
Stan
Posté : 12 août 2005, 09:10
par Cyrano
Le problème n'est pas une question de format de bon de commande ou de méthode de stockage: c'est un problème d'accès ouvert ou non en fonction d'une identification. Tu peux le mettre en postscript ou en flash si ça t'amuse, le problème sera toujours là.
Il faudrait que je plonge dans le code de phpMyShop pour mesurer l'étendue des dégats, mais à mon avis, ce n'est qu'au niveau de l'affichage du bon de commande qu'il faut que tu rajoutes en début de fichier une vérification d'identité. La méthode que j'ai suggéré hier me semble la moins compliquée à mettre en place. Tu récupères lors de l'identification du client les numéros de factures qui lui correspondent s'il en a et tu stockes avec quelque chose dans ce genre.
$sql = "SELECT num_facture FROM commandes WHERE id_client = ". $_SESSION['id_client'] .";";
/* Reste du code de connexion et récupération */
while($num = mysql_fetch_array($requete))
{
array_push($_SESSION['factures'], $num['num_facture']);
}
// ... etc...
Au début de la page bon_de_commande.php (je connais pas le nom exact) tu ajoutes quelque chose du genre:
<?php
session_start();
if(isset($_SESSION['id_client']) AND in_array($_GET['num_facture'], $_SESSION['factures']))
{
// affichage de la facture demandée
}
else
{
header("location: ./index.php");
}
?>
Posté : 12 août 2005, 10:04
par stanthecop
Merci pour cette astuce Cyrano, mais étant débutant, je ne vois pas bien où ajouter ces éléments.
Apparemment la validation de la commande et la création de la facture se font dans un seul et même fichier : facture.php
Le client a une page avec un récapitulatif de sa commande, il entre en dessous ( ou laisse tel quel puisque les données de son compte sont reprises ) l'adresse de livraison puis il valide, la page qui apparait ensuite indique que la commande a bien été prise en compte, et que le client peut cliquer sur un lien pour visualiser le bon de commande ( la fameuse facture accessible à tous... )
Je peux te copier/coller le fichier facture.php si tu le souhaites mais il est un peu long. En même temps je me dis que ça peut être formateur pour bcp de monde et de débutants sur ce forum.
Stan
Posté : 12 août 2005, 10:07
par Cyrano
Je vais regarder le script, faut que je le récupère sur le net, si je trouve, je reviendrai avec une réponse.
Posté : 12 août 2005, 10:26
par stanthecop
Tu pourras trouver ce script sur comscripts.
je te remercie d'avance.
Stan
Posté : 12 août 2005, 10:29
par Cyrano
J'ai plongé un regard dans ce script...

Ça ne fait que me conforter dans mon idée de développer mes scripts moi-même, c'est particulièrement gratiné. En plus il y a de la technique php3 là dedans, et probablement un systèment obligeant à avoir un register_globals à ON...
Désolé, mais pour la réponse, il va falloir du temps, tu feras probablement aussi vite que moi pour la solution suggérée.
Posté : 12 août 2005, 10:34
par stanthecop
Merci d'avance tout de même Cyrano, l'important n'est pas le temps, mais de faire avancer le schmilblick. Je suis certain que les utilisateurs de ce script, et l'auteur lui-même, seront heureux d'en suivre l'évolution.
Concernant ta solution, comme je te disais, je débute vraiment, j'ai passé du temps à adapter le script à mes "couleurs", en changeant les boutons, en modifiant la tva pour afficher du ttc et du tva incluse dans le bon de commande et j'ai peur de tout mettre en l'air en tentant le rajout de ta solution. Si quelqu'un en attendant pouvait m'indiquer où placer les éléments quu tu me donnes, en sachant qu'il s'agit d'un seul et même fichier pour la validation de la commande et la création de la facture, ça serait bien sympa.
Stan
Posté : 12 août 2005, 13:19
par Cyrano
Bon, les nouvelles. Je viens de passer déjà plus de trois heures en débuggage et enfin j'ai réussi à faire une installation qui fonctionne. Entendez par là,
"qui fonctionne sur une machine en mode développeur qui bloque à la moindre erreur"
Maintenant, il s'agit de corriger le reste

Ce script n'est qu'un bug d'un bout à l'autre. Donc je n'en suis pas encore au bon de commande, loin s'en faut. Il faut que j'arrive à voir comment fonctionne le système. Mais déjà, arriver à entrer dans la partie admin sans avoir à s'identifier me semble une abberation à la base. Le système de session est à vérifier. J'espère que tu n'es pas à la minute, je risque fort d'y passer pas mal de temps.