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

PHP & Base de données Discussion :

Tables vidées et injection mysql


Sujet :

PHP & Base de données

  1. #1
    Membre éprouvé
    Inscrit en
    Mars 2004
    Messages
    1 931
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 1 931
    Par défaut Tables vidées et injection mysql
    Bonjour, à tous,

    voilà j'ai subi récemment à deux reprises des attaques sur mon site.
    Ces attaques ont eu pour conséquences de supprimer des tables de ma bases de données.

    voici un exemple de mes requêtes, pouvez-vous me dire si elles sont bien protégées des injections mysql :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // Protège la variable avant l'insertion
    function quote_smart($value){
    // Stripslashes si nécessaire
            if (get_magic_quotes_gpc()){
                    $value = stripslashes_deep($value);
            }
    // Protection si ce n'est pas un entier
            if (!is_int($value)){
                    $value = "'" . mysql_real_escape_string($value) . "'";
            }
    return $value;
    }
    $sqly = sprintf("delete from flatforswap_adherent where id_adh=%s", quote_smart($_GET['id']));
    $reqy = mysql_query($sqly) or die('Erreur SQL : <br />'.$sqly);
     
    $sql_des = sprintf("delete from flatforswap_destination where id_adh=%s", quote_smart($_GET['id']));
    $req_des = mysql_query($sql_des) or die('Erreur SQL : <br />'.$sql_des);
     
    $sql_log = sprintf("delete from flatforswap_logement where id_adh=%s", quote_smart($_GET['id']));
    $req_log = mysql_query($sql_log) or die('Erreur SQL : <br />'.$sql_log);
    Merci d'avance pour votre aide.

  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Ces attaques ont eu pour conséquences de supprimer des tables de ma bases de données.
    pouvez-vous me dire si elles sont bien protégées des injections mysql
    T'as pas l'impression que la réponse est dans la question ?
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  3. #3
    Membre expérimenté
    Homme Profil pro
    Consultant PLM
    Inscrit en
    Août 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant PLM

    Informations forums :
    Inscription : Août 2007
    Messages : 203

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juillet 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 26

  5. #5
    Membre éprouvé
    Inscrit en
    Mars 2004
    Messages
    1 931
    Détails du profil
    Informations forums :
    Inscription : Mars 2004
    Messages : 1 931
    Par défaut
    Salut nels77, je l'ai bien testé mais je n'ai rien compris au rapport, de plus je me suis renseigné et il paraît que ce n'est pas fiable...

    Une remarque, pour écrire mon code, je me suis inspiré de cet note :

    Si elle n'est plus d'actualité et donc plus efficace, pourquoi la laisser toujours en ligne..

  6. #6
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Parce qu'elle est toujours valable, tant que tu utilises l'API mysql_. Ce n'est pas parce qu'on a inventé le robot-mixeur qu'on ne peut plus faire de soupe avec un moulin à légumes.
    Cela étant dit, l'API mysql_ est considérée comme obsolète et il est recommandé de passer à mysqli ou PDO. (Note : obsolète ne veut pas forcément dire que ça ne marche plus, ça veut dire que ça va disparaitre dans une prochaine version)

    A vue de nez, tes requêtes ont l'air propre. Es-tu sûr que le problème vient de là ? Pas d'interface PhpMyAdmin accessible facilement ? Tu es sur un hébergement dédié ?
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  7. #7
    Expert confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 418
    Par défaut
    Salut,

    Dans le titre de ton message, tu dis que tes tables ont été vidées et ensuite tu dis "supprimées"...

    Si elles ont été simplement vidées c'est peut-être que tu ne fais pas de contrôle sur le $_GET['id']... Et dans ce cas on peut supprimer ce qu'on veut (en envoyant une série de requêtes avec un id différent) bien qu'il n'y ai pas d'injection sql à proprement parler.

    Si tu es entrain de faire ton code, autant utiliser PDO. Avec des requêtes préparées tu as une meilleure sécurité contre les injections sql (mais cela ne te dispenserait pas de contrôler les variables permises dans la requête). Et puis en tant que débutant, autant ne pas apprendre du code obsolète dont le manuel précise qu'il est déconseillé pour les nouveaux projets. Tu es simplement tombé sur un topic un peu ancien...

  8. #8
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Effectivement, si ton script de suppression s'appelle par quelque chose du genre delete.php?id=1, il suffit de faire un appel en boucle avec un truc qui incrémente le nombre et pouf! ta base est vide

    Donc, il s'agit davantage de validation que de sécurité. Par exemple, ya-t-il un système d'authentification, avec des droits différents ?
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  9. #9
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $sqly = sprintf("delete from flatforswap_adherent where id_adh=%s", quote_smart($_GET['id']));
    Tu fais quoi par exemple si le paramètre reçu est 1 OR 1=1 ?
    Ca transformerait ta requête en
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    delete from flatforswap_adherent where id_adh=1 OR 1=1
    et tu laisses passer sans vérification quelconque...
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 101
    Par défaut
    Bonjour,

    Une petite ramarque sur ta fonction :

    Citation Envoyé par sam01 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function quote_smart($value){
    // Stripslashes si nécessaire
            if (get_magic_quotes_gpc()){
                    $value = stripslashes_deep($value);
            }
    // Protection si ce n'est pas un entier
            if (!is_int($value)){
                    $value = "'" . mysql_real_escape_string($value) . "'";
            }
    return $value;
    }
    Comme son nom l'indique, get_magic_quotes_gpc indique le paramétrage de quotes automatiques pour les paramètres GET, POST et COOKIE, d’où le GPC à la fin du nom de la fonction.
    Ta fonction n'as pas pour "unique" but de traiter les variables Get, Post et Cookie, puisqu'elle prend une variable en paramètre qui peut très bien être une variable autre que GPC.

    Ton test de stripslashes n'as donc rien à faire ici, tu devrai te faire une fonction de récupération de variable GPC qui, elle, posséderait ce test et le retirer de ta fonction de protection de paramètre de requêtes BDD.

  11. #11
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $sqly = sprintf("delete from flatforswap_adherent where id_adh=%s", quote_smart($_GET['id']));
    Tu fais quoi par exemple si le paramètre reçu est 1 OR 1=1 ?
    Ca transformerait ta requête en
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    delete from flatforswap_adherent where id_adh=1 OR 1=1
    et tu laisses passer sans vérification quelconque...
    Euh... ya quand même mysql_real_escape_string dans sa fonction quote_smart. Sauf erreur de ma part, mysql_real_escape_string sert justement à éviter ce genre de problème.
    Ou alors j'ai loupé quelque chose ?
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  12. #12
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Bah non, je crois pas... Sauf erreur de ma part (ou de mes yeux)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo mysql_real_escape_string('1 OR 1=1');
    retourne bien
    1 OR 1=1
    sans échappement.
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  13. #13
    Modérateur
    Avatar de BakSh0
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2014
    Messages
    276
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2014
    Messages : 276
    Par défaut
    En effet mysql_real_escape_string n'empêchera pas l'utilisateur de passer un 1 OR 1=1.

    Mais dans ce cas un intval() ou un cast (int) ou un test avec is_numeric() est une solution.

    Attention un intval("1 OR 1=1;"); donnera 1, donc faire un contrôle tout de même pour ne pas faire supprimer un id=1 (comme un admin par exemple)

    Cela dit faire un delete d'un paramètre GET sans aucun contrôle ça me parait étrange, ce qui ne t'empêche pas d'utiliser PDO et les requêtes préparées comme le dit à juste titre ABCIWEB.

    L'info inutile : (int) serait plus rapide que intval
    BakSh0, Modérateur .Net & Web

    Affichez la colorisation syntaxique dans votre code en ajoutant dans votre balise : [CODE=xxx] en remplaçant xxx par le nom du langage.


    N'oubliez pas de consulter les FAQs : .Net / Web et les cours et tutoriels .Net / Web

  14. #14
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    Sa fonction quotesmart ajoute les apostrophes, donc on obtient bien WHERE id_adh='1 OR 1=1'Donc soit il existe une chaine de caractères avec du code SQL qui valide is_int() ... mouais, soit le problème vient d'ailleurs : non utilisation de la fonction quotemsart() quelque part ou l'attaque n'est pas une injection SQL.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  15. #15
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Je parierais plutôt pour une non-injection, mais là on va pas pouvoir deviner

    @Bovino :
    Après relecture attentive de la doc :
    mysql_real_escape_string() appelle la fonction mysql_escape_string() de la bibliothèque MySQL qui ajoute un anti-slash aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a.
    Donc effectivement, ça ne protège pas du bon vieux "OR 1=1". Autant pour moi.
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  16. #16
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Autant pour moi.
    Je ne temps veux pas, histoire de commettre une faute d'orthographe digne de la tienne !
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  17. #17
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Par défaut
    En fait l'erreur serait d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'WHERE colonne_int = ' . mysql_real_escape_string($code_malveillant);
    On a l'impression d'avoir tout bien fait et pourtant ...

    Je comprends mieux pourquoi PHP encourage les requêtes préparées.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  18. #18
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Bref, à l'intention du posteur d'origine : laisse tomber mylsq_ et passes à mylsqi et aux requête préparées.

    Citation Envoyé par Bovino Voir le message
    Je ne temps veux pas, histoire de commettre une faute d'orthographe digne de la tienne !
    Tu m'en dira temps c'est p'tet pas reconnu par l'académie française, mais c'est quand même du langage courant. Et franchement, c'est mieux que d'écrire "arrosage" pour "spammer"...
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  19. #19
    Expert confirmé

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 418
    Par défaut
    Citation Envoyé par Celira Voir le message
    Bref, à l'intention du posteur d'origine : laisse tomber mylsq_ et passes à mylsqi et aux requête préparées.
    Sabotage a cité ici le cas typique où la protection de mysql_real_escape_string est inefficace mais la protection mise en place dans le code original ne permettait pas cette syntaxe comme il le faisait aussi remarquer là. La chaine de caractères étant entourée de quote, un 'OR' ne serait pas interprété comme une commande sql...

    Donc si ton conseil est bon sur le principe, dans ce cas cela risque fort de ne pas suffire. Il est très peu probable que l'on puisse réussir une injection sql dans le code montré, le problème vient d'ailleurs, par exemple d'un accès non protégé à ce code, ou d'un vol de session ou... mais passer à mysqli ou à pdo ne résout pas ces problèmes

    Autre petite remarque, je conseillerais plutôt à un débutant de passer directement à PDO.
    Il vaut mieux réserver l'utilisation de mysqli pour mettre à jour un vieux code mysql si besoin, sinon le passage par mysqli n'est pas une étape intéressante. La syntaxe PDO est infiniment plus agréable à écrire (plus courte) et il existe des fonctionnalités très pratiques (comme passer un tableau de paramètre dans le execute()) qui la rend aussi beaucoup plus souple, sans compter une meilleure portabilité.
    Au départ je suis passé de mysql à mysqli par facilité/manque de temps. Et puis pdo étant tellement plus agréable, un an plus tard je me suis mis à pdo. Bah du coup, il a fallu que retransforme tous mes codes génériques de mysqli vers pdo. Au final, j'aurais eu plus vite fait de prendre du temps dès le départ pour passer directement à pdo...

Discussions similaires

  1. Table vidée de ma base de données mysql
    Par sam01 dans le forum Sécurité
    Réponses: 6
    Dernier message: 27/01/2015, 10h54
  2. [OpenOffice][Base de données] Tables vides en migrant de HSQL vers MySQL
    Par Macgiver75 dans le forum OpenOffice & LibreOffice
    Réponses: 1
    Dernier message: 05/03/2014, 21h38
  3. Tables vides en migrant de HSQL vers MySQL
    Par Macgiver75 dans le forum Installation
    Réponses: 0
    Dernier message: 06/02/2014, 21h58
  4. [MySQL] PHP-MySQL: Insertion de donnée dans une table vide
    Par jrosenzw dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 07/03/2009, 02h11
  5. Probleme avec une table vide
    Par king dans le forum Bases de données
    Réponses: 5
    Dernier message: 20/03/2004, 14h24

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