IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Procédural MySQL Discussion :

Facile de déclencher une erreur mysql_fetch_array


Sujet :

SQL Procédural MySQL

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    531
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 531
    Par défaut Facile de déclencher une erreur mysql_fetch_array
    Bonjour,

    Je viens de penser à un petit (gros ?) trou de sécurité dans le forum que j'ai programmé.
    J'ai des liens comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    http://www.site.com/sujet-choix.php?affichage=1&debut=10
    ici ?debut=10 c'est le nombre de tuples à aller chercher. C'est une variable dont la valeur sert de paramètre à la requête sql.
    Si on entre quoi que ce soit d'autre qu'un chiffre, la requête génère l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in /home.2/site/scripts/compte/compte/sujet-choix.php on line 82
     
    Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource in /home.2/site/scripts/compte/compte/sujet-choix.php on line 135

    Bien sûr je filtre la variable $_GET[debut] par htmlspecialchars et mysql_real_escape_string.
    Mais tout de même, je pense que le fait d'afficher ces erreurs est mauvais pour la sécurité, ne serait-ce que parce que cela donne des informations sur le serveur (même si pour le moment c'est un mutualisé).


    Une solution consiste donc à n'exécuter la requête que si le masque est corrrect, sinon on ne fait rien.
    Dans les autres pages je n'ai pas ce problème car il y a un url rewriting qui génère une page d'erreur.

    Voilà, qu'en pensez-vous ? Je fais un preg_replace pour tester le masque de la variable ? Je le fais aussi sur les pages de l'url rewriting où c'est pas la peine sur celle-ci ?(j'ai déjà vu que yahoo affiche les pages avec des urls non rewritées).


    Merci pour vos conseils (de pros si possible)

  2. #2
    Membre Expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Par défaut
    Bonjour
    Juste un point de vue très général sur la question :

    - phase de développement : on affiche TOUTES les erreurs, et on se débrouille pour qu'il n'en apparaisse plus aucune. Effectivement il faut faire attention à ce qu'on appelle l'injection SQL, le fait de mettre autre chose que ce qui est attendu dans une requête. Il faut donc toujours vérifier la cohérence des informations fournies par l'utilisateur (et éviter les exécutions de code externe).
    - phase de production: on n'affiche plus les erreurs, mais par contre on reste conscient qu'il n'est plus censé en avoir, alors on les fait interpréter par le script, et on prévient un admin, un développeur... (envoi d'un mail, écriture dans un journal)

    dans le php.ini, il y a une valeur display_errors qui pourra donc être mise à Off en production. On pourra aussi utiliser log_errors et les valeurs associées.
    On vérifiera avec soin toutes les valeurs de retour.

    On peut également configurer un gestionnaire d'erreurs personnalisé avec la fonction set_error_handler.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    531
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 531
    Par défaut
    Je te remercie de ta réponse Eusébius.
    Bon je reprend :
    - phase de développement : on affiche TOUTES les erreurs, et on se débrouille pour qu'il n'en apparaisse plus aucune.
    Ce n'est pas volontaire, je n'ai pas de mysql_error par exemple, simplement ça fait bugger le script, je ne peux rien y faire.

    Effectivement il faut faire attention à ce qu'on appelle l'injection SQL, le fait de mettre autre chose que ce qui est attendu dans une requête.
    mysql_real_escape_string doit supprimer les risques déjà (ou très fortement les réduire, y'a toujours des bêtes du piratage, mais bon....). Cela étant ce n'est pas une raison pour laisser s'afficher le message d'erreur dont j'ai parlé.
    Il faut donc toujours vérifier la cohérence des informations fournies par l'utilisateur (et éviter les exécutions de code externe).
    Le problème c'est que quand le champ est un input text qui peut recevoir n'importe quoi, on ne peut plus utiliser les expreg, il ne reste mysql_real_escape_string (ceci dit ce type de champ ne contiennent normalement pas de valeur passées en paramètre aux requêtes, donc pas de problème comme celui que je rencontre en ce moment).

    - phase de production: on n'affiche plus les erreurs, mais par contre on reste conscient qu'il n'est plus censé en avoir, alors on les fait interpréter par le script, et on prévient un admin, un développeur... (envoi d'un mail, écriture dans un journal)
    Comment faire pour être averti par mail ou par requête sql qu'une erreur vient de se déclencher dans la page ?

    Pour le reste c'est du mutualisé je ne crois pas pouvoir modifier le php_ini.

  4. #4
    Membre Expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Par défaut
    Juste histoire de préciser, ce que j'ai dit n'était pas personnalisé : j'ai pas forcément dit que tu ne faisais pas ce que je conseillais.

    Citation Envoyé par JackBeauregard
    Ce n'est pas volontaire, je n'ai pas de mysql_error par exemple, simplement ça fait bugger le script, je ne peux rien y faire.
    Tu fais tes requêtes comme précisé dans ma signature ?

    Citation Envoyé par JackBeauregard
    Le problème c'est que quand le champ est un input text qui peut recevoir n'importe quoi, on ne peut plus utiliser les expreg, il ne reste mysql_real_escape_string (ceci dit ce type de champ ne contiennent normalement pas de valeur passées en paramètre aux requêtes, donc pas de problème comme celui que je rencontre en ce moment).
    Si tu as des spécifications précises, tu dois pouvoir définir un certains nombre de critères pour chaque entrée, qui limitent déjà les possibilités d'erreur (i.e. c'est un nombre, il est compris entre tant est tant, il n'y a pas tel ou tel caractère...)

    Citation Envoyé par JackBeauregard
    Comment faire pour être averti par mail ou par requête sql qu'une erreur vient de se déclencher dans la page ?
    Avec set_error_handler, tu peux spécifier une fonction à appeler en cas d'erreur. Cette fonction, c'est toi qui l'écris donc tu en fais ce que tu veux ! C'est très intéressant comme procédé.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    531
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 531
    Par défaut
    Tu fais tes requêtes comme précisé dans ma signature ?
    Non je n'utilise pas die et mysql_error() sauf si j'ai une erreur quand je programme et encore en général j'y pense pas (j'ai peur d'oublier de l'enlever).
    Dans le cas présent, la requête fonctionne bien, elle attend simplement un nombre et si on entre autre chose dans l'url (ce que l'on est pas censé faire...), alors ça fait bugger le script.
    Je filtre l'entré, mais tout de même je crois que je vais faire un preg_replace() pour supprimer cette erreur.

    Si tu as des spécifications précises, tu dois pouvoir définir un certains nombre de critères pour chaque entrée, qui limitent déjà les possibilités d'erreur (i.e. c'est un nombre, il est compris entre tant est tant, il n'y a pas tel ou tel caractère...)
    Je me demande si c'est vraiment la peine pour l'intégralité des formulaires.
    Par exemple, j'ai un script qui réagit si $_POST['var']==1.
    Je filtre la variable htmlentities(mysql_real_escape_string()) de toute façon. Mais si $_POST['var'] n'est pas égal à 1 ça ne fera rien c'est tout, la valeur n'est pas passée en paramètre à une variable contrairement au cas que j'ai expliqué au début.
    Et si le gars m'envoit une injonction sql, elle atterira dans la base, mais cassée par mysql_real_escape_string().
    Avec set_error_handler, tu peux spécifier une fonction à appeler en cas d'erreur.
    Ok, je connaissais pas cette fonction, merci de me la faire découvrir. ça m'a pas l'air évident à utiliser, mais quand je serai dessus je posterai à propos si nécessaire.

  6. #6
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 509
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 509
    Par défaut
    Dans mes developpement, j'aime controler ce que je donne à manger à ma base car il lui faut lui donner de la nourriture saine .
    Là ou il attend une valeur numérique il y aura une une valeur numérique garantie. De plus je m'assure que cette valeur existe bien dans la base de données. Si c'est pas le cas c'est que quelqu'un s'amuse à changer les valeurs pour provoquer quelque chose.
    Je fais en sorte limiter le maximum d'information passé en url ou champs caché. Je compte sur l'intégrité et la justesse des informations déjà présente.
    L'entrée et la sortie de ma base de données passe toujours par un objet via les accesseurs correspondant ainsi les variables sont typé (façon de voir); Exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Class Toto{
        private $id;
     
       public Function setId($pId){
          $this->id = (integer) $pId;
        }
     
      public Function getId(){
        return (integer) $this->id;
      }
     
    }

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    531
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 531
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ou il attend une valeur numérique il y aura une une valeur numérique garantie.
    Ok mais souvent c'est des champs varchars et à part un htmlspecialchars(mysql_real_escape_string()) je vois pas trop quoi faire d'autre.

    Je fais en sorte limiter le maximum d'information passé en url ou champs caché.
    Je les filtre aussi, donc pourquoi les limiter ?

    En fait je vois pas comment le gars peut contourner un htmlspecialchars(mysql_real_escape_string()) sur chaque champ à part si c'est un pro et qu'il en veut vraiment. Pour certains script j'utilise quand même les expressions régulières.
    Or justement le problème dans le cas que j'ai évoqué c'est que les valeurs ne sont pas envoyées dans la base (auquel cas mysql_real et htmlspecialchars font l'affaire) , mais sont passées en paramètre à la requête sql : et là ça déclenche un bug, parce que les valeurs ne sont pas conformes à celle attendues : d'où la nécessité de controler la nature des valeurs passées à la requêtes.

    Mais tu me déclenches un doute : que ce passe-t'il si le pirate bidouille un faux formulaire pour trafiquer les champs hidden et s'en sert pour balancer des données qui ne correspondent pas à la nature du champ censé les recevoir (par exemple un champ smallint qui reçoit des chars, mêmes filtrées par les fonctions déjà évoquées) ?
    Cela va-t'il déclencher un bug fatidique utilisable par le pirate ?
    Dans mon expérience, les données ne sont simplement pas enregistrées mais c'est à vérifier.

  8. #8
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 509
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 509
    Par défaut
    pour eviter qu'une personne puisse faire sa propre page et post sur ton serveur. Je place toujours en bas de mon fichier php un
    session['from'] = $_SERVER['SCRIPT_NAME'].
    Même si le pirate arrive a avoir la session il ne peut pas modifier son contenu et le faire mentire.

    Concernant les filtres sur l'url c'est que je veux pas qu'un pirate puisse manipuler les données et créer des incohérence. Je donne un exemple.
    Je veux récupérer un produit #23 qui se trouve dans la categorie #12
    ...?idcategorie=12&idproduit=23

    Pour moi ça c'est une erreur de conception mais que nous retrouvons assez souvent. De plus selon les interactions ça peut poser problème. Que se passe t'il s'il place un idproduit qui ne se trouve pas dans la catégorie indiqué ???


    C'est en ça que je parle de limiter les informations passé en url

  9. #9
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    531
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 531
    Par défaut
    pour eviter qu'une personne puisse faire sa propre page et post sur ton serveur. Je place toujours en bas de mon fichier php un
    session['from'] = $_SERVER['SCRIPT_NAME'].
    Même si le pirate arrive a avoir la session il ne peut pas modifier son contenu et le faire mentire.
    L'idée a l'air pas mal du tout, mais je ne pige pas du tout son fonctionnement.
    Je viens de tapper session['from'] dans google, je n'ai rien trouvé, idem pour $_SERVER['SCRIPT_NAME']. Je ne pige pas ce que tu entends par là, ni comment ça peut fonctionner.

    Concernant les filtres sur l'url c'est que je veux pas qu'un pirate puisse manipuler les données et créer des incohérence. Je donne un exemple.
    Je veux récupérer un produit #23 qui se trouve dans la categorie #12
    ...?idcategorie=12&idproduit=23

    Pour moi ça c'est une erreur de conception mais que nous retrouvons assez souvent. De plus selon les interactions ça peut poser problème. Que se passe t'il s'il place un idproduit qui ne se trouve pas dans la catégorie indiqué ???


    C'est en ça que je parle de limiter les informations passé en url
    Ok je vois le truc, donc tu fais un test pour savoir, dans ce cas, si l'id est bien dans une fourchette prédéterminée ? Le truc c'est d'ensérer le plus possible les données expédiées à la base dans des choix prédéterminés, en fait.
    Bon ceci dit ce n'est pas cela qui va permettre au pirate de réussir son coup je pense. A moins que comme j'ai dit, le fait d'envoyer un varchar quand la table attend un int ne puisse déclencher une erreur, ce qui me semble n'est pas le cas, puisqu'alors la base refuse d'enregistrer la valeur, selon ce que j'ai pu voir.
    Qui confirme/infirme (de toute façon je me vois mal faire une expression régulières pour tous les champs de mes tables et puis dans certains cas, les varchars justement, c'est impossible).

  10. #10
    Membre Expert

    Profil pro
    imposteur
    Inscrit en
    Avril 2003
    Messages
    3 308
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : imposteur

    Informations forums :
    Inscription : Avril 2003
    Messages : 3 308
    Par défaut
    Citation Envoyé par JackBeauregard
    L'idée a l'air pas mal du tout, mais je ne pige pas du tout son fonctionnement.
    Je viens de tapper session['from'] dans google, je n'ai rien trouvé, idem pour $_SERVER['SCRIPT_NAME']. Je ne pige pas ce que tu entends par là, ni comment ça peut fonctionner.
    Peut-être qu'il voulait dire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $_SESSION["from"] = $_SERVER["PHP_SELF"];
    Histoire de vérifier la provenance ?
    Mais ptet que j'ai pas compris, aussi

  11. #11
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 509
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 509
    Par défaut
    Effectivement c'est une erreur de ma part. Je voulais dire $_SESSION['from'] comme ça aurait pu être toto .

    Concernant la cohérance des information passé en url je voulais dire qu'il fallait éviter de passer trop d'information alors qu'il est possible de le récupérer dans le serveur. Exemple l'idarticle étant associé à une catégorie peut être récupéré par une jointure sql ou objet. Ce n'est qu'un exemple mais pour dire qu'avec une application bien ficelé il peut y avoir un minimum d'information qui transite. Moin d'information = moin de possibilité pour le pirate de créer des erreurs.

    Quand tu parles du type de champs attendu . Si la table attend un int et on lui balance varchar il faut éviter que ça soit le SGBD qui contrôlle l'information mais bien avant. Si tu vois que le fruit est pourri tu vas pas le manger en te disant que tu fais confiance à ton estomac pour le rejeter c'est ton oeil et éventuellement ton nez qui t'on alerté.

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    531
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 531
    Par défaut
    Bon je marque résolu, et je viens d'ouvrir un sujet plus général ici, parce que pour la question de ce post, la réponse est évidente : je dois utiliser les expreg pour filtrer les variables passées en paramètre via l'url à mes requêtes.

    La suite ici :
    http://www.developpez.net/forums/sho...81#post1127281


    Merci à vous

  13. #13
    Membre confirmé Avatar de kivan666
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Par défaut mais quel interet ??
    je viens de lire ce topic et un point m'échappe...
    Ok, si l'utilisateur s'amuse à remplacer les paramètres de l'URL à la main il va réussir à déclencher une erreure SQL...
    super... mais quel interet pour ce "hackeur" ?? voir une liste d'erreure ??
    je veux dire, son but c'est de récupérer un pass, on d'effacer des données... afficher des erreure n'a aucun interet...
    ou alors un point m'a achappé... merci de m'éclairer...

  14. #14
    Membre éprouvé
    Avatar de berceker united
    Profil pro
    SQL
    Inscrit en
    Février 2005
    Messages
    3 509
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SQL
    Secteur : Finance

    Informations forums :
    Inscription : Février 2005
    Messages : 3 509
    Par défaut
    Le message d'erreur peut donner des informations assez précieuse pour un hackeur. Donner le chemin du fichier qui traite les opération sql par exemple. Il suffit qu'il se connecte directement sur ce fichier et travailler directement dessus. Par exemple a.php gère la sécurité d'entrée dans la base. b.php gere l'insertion en base. si l'hacker attaque directement b.php il a zappé la sécurité.

  15. #15
    Membre confirmé Avatar de kivan666
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 242
    Par défaut
    mmm je vois... je n'y avais pas pensé car chez moi tout est toujours dans la même page...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Déclencher une erreur personalisé dans un Trigger
    Par Soulangel dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 26/05/2013, 14h38
  2. Déclencher une erreur dans main.
    Par jeremux dans le forum C
    Réponses: 2
    Dernier message: 07/10/2011, 14h59
  3. Déclencher une erreur "perso" dans un trigger
    Par sebpern dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 20/04/2010, 19h11
  4. CGI déclencher une erreur
    Par Watier_53 dans le forum C
    Réponses: 4
    Dernier message: 22/07/2008, 15h11
  5. [SGBD] mysql_fetch_array provoque une erreur
    Par nicerico dans le forum Requêtes
    Réponses: 6
    Dernier message: 06/10/2005, 14h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo