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 :

PHP Cybersécurité - requêtes SQL


Sujet :

PHP & Base de données

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    étudiant
    Inscrit en
    juin 2020
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2020
    Messages : 68
    Points : 38
    Points
    38
    Par défaut PHP Cybersécurité - requêtes SQL
    Bonjour,

    Je suis en reconversion pro en BTS SIO.

    Si part le plus grand des hasards quelqu'un bosse à l'éducation nationale passe par là, le contenu demandé en première année de BTS SIO est juste ridicule:
    Python, C#, Java, HTML, CSS, Bootstrap, WordPress, Javascript, MySQL, POSTGRESQL, NoSQL, Sciences-eco, Droit, Management, Culture Gé.

    Dans toutes ces connaissances additionnées les unes à la suite des autres traitées n'importe comment (on a 10 pages de cours sur le Web pour chaque langage et on nous demande d'apprendre seuls) il faut aussi rajouter la Cybersécurité. Dans ce cours on nous demande de détecter les failles de sécurité dans un code en PHP mais on n'a pas de cours de PHP.
    Le prof nous dit que l'on est sensé comprendre un code d'un langage que l'on n'a jamais vu...

    Analysez le code qui permet de vérifier la connexion d’un utilisateur sur le module interne. Peut-on dire que le système est sécurisé ? Indiquez les éléments sécurisés et non sécurisés ?

    Proposez les améliorations à apporter (tenir compte de tous les aspects).

    Proposez le code modifié de la connexion (soit en PHP soit en pseudo-code). Si vous apportez des modifications hors du code veuillez les préciser) ?
    En cherchant sur internet je suis tombé sur les articles suivants. Je pense que cela pourrait répondre à la question mais je ne sais pas si cela est pertinent par rapport aux questions posées :
    https://www.php.net/manual/fr/securi...-injection.php

    Sur le lien ils citent :
    • risque de séparation des résultats en pages, et créer des administrateurs (PostgreSQL et MySQL). Là les variables sont différentes mais est-ce que ce serait la même chose entre pass = $_POST['pass']; ?
    • injection SQL
    • ajout de mot de passe
    • révélation des mots de passe
    • modifier un mot de passe ... et gain de droits
    • attaque d'un serveur de base de données



    Je pense que ces éléments doivent pouvoir répondre à la question mais je n'arrive pas à les associer avec le code ci-dessous.
    Si quelqu'un pourrait m'aider je lui en serai très reconnaissant.
    Si vous pourriez également proposer un contenu pour apprendre PHP (gratuit si possible, j'en ai marre de devoir payer des cours parce que les profs ne donnent pas de cours, merci le CNED hein ?) et quel IDE vous recommander pour apprendre.


    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    <?php   
          $pseudo = $_POST['pseudo'];  
          $pass = $_POST['pass'];
     
     
    include ('pdo.php');
     
    / Vérification des identifiants
    $req = $bdd->prepare('SELECT * FROM salarie WHERE pseudo = :pseudo);
    $req->execute(array(    
          'pseudo' => $pseudo
    ));
    
    $resultat = $req->fetch();
    
    if (!$req)
    {    
          echo 'Mauvais identifiant ou mot de passe !';
    }
    else
    {
    switch ($req ['group']) {    
              case 'Assistant':        
                       $pass_std = 'PswAss' .$req ['region'];        
                       break;    
              case 'Agent':        
                       $pass_std = 'Pswagt' .$req ['region'];        
                       break;    
              case 'Responsable':        
                       $pass_std = 'Pswresp' .$req ['region'];        
                       break;
    }    
            if ($pass_std ==$pass )    
            {     
                   echo 'Vous êtes connecté !';    
            }    
           else    
            {     
              echo 'Mauvais identifiant ou mot de passe !';    
            }
    }

    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
    21
    22
    23
    24
    25
    <?php 
     
    include ('pdo.php');
     
    $fiche = [                     
                      'NOM'=> $_POST['NOM'],                     
                      'PRENOM'=> $_POST['PRENOM'],                    
                      'ADRESSE'=> $_POST['ADRESSE'],                    
                      'VILLE'=> $_POST['VILLE'],                    
                      'CP'=> $_POST['CP'],                    
                      'PAYS'=> $_POST['PAYS'],                    
                      'TEL'=> $_POST['TEL'],                    
                      'MAIL'=> $_POST['MAIL'],                    
                      'AGE'=> $_POST['AGE'],                    
                      'COUPLE'=> $_POST['COUPLE'],                    
                      'NBENFANT'=> $_POST['NBENFANT'],                    
                      'LOGIN'=> $_POST['LOGIN'],                    
                      'PSW'=> sha1($_POST['PSW'],
    ]; 
     
    // Vérification des identifiants
    $req  =  ('INSERT  INTO  VISITEUR  (NOM,PRENOM,ADRESSE,VILLE,CP,PAYS,TEL,MAIL,AGE,COUPLE,NBENFANT,LOGIN,PSW)  VALUES  (  :NOM,  :PRENOM,  :ADRESSE,  :VILLE,  :CP,  :PAYS,  :TEL,  :MAIL,  :AGE,  :COUPLE,  :NBENFANT, :LOGIN, :PSW));
    
    $stmt= $pdo->prepare($req);
    $stmt->execute($fiche);

  2. #2
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Architecte Web / Android
    Inscrit en
    août 2003
    Messages
    6 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Architecte Web / Android
    Secteur : Industrie

    Informations forums :
    Inscription : août 2003
    Messages : 6 242
    Points : 17 909
    Points
    17 909
    Par défaut
    La quantité de technos abordées c'est propre à un peu près toutes les formations. C'est pour faire croire qu'une fois le diplôme en poche on est des superstars qui savent tout faire. Faut faire avec

    Pour ta question, le risque d'attaque existe sur une requête SQL quand on lui passe des paramètres (un login et mot de passe par exemple) sans les vérifier.

    Cette vérification peut se faire de plein de façons différentes.
    - Vérification de type (est ce que age est bien un entier par exemple)
    - Filtrage des caractères dangereux (ajout de caractère d'échappement)
    - Préparation de la requête

    La préparation de la requête est la plus couramment utilisé car ca évite les oublie et c'est très efficace.
    Le principe de la préparation de requête est de dire :

    Voici la requête à exécuter : "SELECT * FROM matable WHERE champs = :parametre"
    Voici les paramètres de ta requête : ":paramètre = 'toto';

    Le moteur de base de données va donc "compiler" la requête sans les paramètres => aucun risque d'exécuter quoi que ce soit car aucune entrée utilisateur. Puis y adjoindre les paramètres qui eux ne seront pas jamais exécutés par le moteur bdd mais simplement ajouter à la requête "pré copmpilé".

    Au contraire une requête plus traditionnelle pose problème car toute la chaine est exécuté et donc si des paramètre contiennent du code malicieux il est exécuté.

    La règle universelle est : "Never trust user input" , Ne jamais faire confiance au données utilisateur. Donc tout ce qui vient de l'extérieur (via formulaire par exemple) doit être traité d'une manière ou d'une autre.
    Quand c'est pour sauvegarder une donnée :
    - Requête préparée et / ou filtrage et/ou validation de la données

    Quand c'est pour afficher la données
    - Filtrage et protection pour éviter les failles de type XSS. (htmlentities,htmlspecialchars font le job).

    En complément tu peux jeter un oeil aux slides d'un cours que je donne sur la sécurité , en particulier la partie liée aux injections : https://grunk.github.io/sec_dev/#/6/6 (en appuyant sur "S" de ton clavier tu aura accès au speaker note qui pourront aider un peu à comprendre les slides, tu navigue dans les slides avec les touches fléchées)
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    étudiant
    Inscrit en
    juin 2020
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2020
    Messages : 68
    Points : 38
    Points
    38
    Par défaut
    Citation Envoyé par grunk Voir le message
    La quantité de technos abordées c'est propre à un peu près toutes les formations. C'est pour faire croire qu'une fois le diplôme en poche on est des superstars qui savent tout faire. Faut faire avec

    Pour ta question, le risque d'attaque existe sur une requête SQL quand on lui passe des paramètres (un login et mot de passe par exemple) sans les vérifier.

    Cette vérification peut se faire de plein de façons différentes.
    - Vérification de type (est ce que age est bien un entier par exemple)
    - Filtrage des caractères dangereux (ajout de caractère d'échappement)
    - Préparation de la requête
    Merci beaucoup pour votre retour et pour le tutoriel très intéressant.
    Mais dans le cas présent de l'exercice il y a un test sur le mot de passe non ?
    Je vois une condition if ... else... mais d'ailleurs dans le code il y a 2 fois un if ... else...
    Je ne saisis pas ce que fait chacun des if ... else...

    Cordialement
    Mathieu

  4. #4
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Architecte Web / Android
    Inscrit en
    août 2003
    Messages
    6 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Architecte Web / Android
    Secteur : Industrie

    Informations forums :
    Inscription : août 2003
    Messages : 6 242
    Points : 17 909
    Points
    17 909
    Par défaut
    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
    <?php   
     
    // Récupération des valeurs depuis un formulaire
    $pseudo = $_POST['pseudo'];  
    $pass = $_POST['pass'];
     
     
    include ('pdo.php');
     
    // ON recherche  toutes les infos dans la table salarie pour l'entrée ayant un certains pseudo
    $req = $bdd->prepare('SELECT * FROM salarie WHERE pseudo = :pseudo'); // Préparation de la requête
    $req->execute(array(    
          'pseudo' => $pseudo // ici c'est ':pseudo' qu'il faudrait utiliser
    )); // Execution de la requête en lui associant en paramètre le pseudo
     
    $resultat = $req->fetch(); // Récupération du résultat
    Voilà pour le début du code.

    Pour la suite ca ne sert à rien puisqu'il est complètement faux.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (!$req) // Si l'execute c'est mal passée (erreur de requête par exemple)
    {    
          echo 'Mauvais identifiant ou mot de passe !';
    }
    $req vaudra false en cas d'erreur (sur la requête par exemple). Si on veux vérifier qu'on à pas trouvé de résultat il faudrait vérifier que $resultat est vide

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    switch ($req ['group']) {    
    		case 'Assistant':        
    			   $pass_std = 'PswAss' .$req ['region'];        
    			   break;    
    		case 'Agent':        
    			   $pass_std = 'Pswagt' .$req ['region'];        
    			   break;    
    		case 'Responsable':        
    			   $pass_std = 'Pswresp' .$req ['region'];        
    			   break;
    	}
    Ca ne peut pas marcher. $req ne contient pas les données. C'est résultats qui potentiellement peux les contenir.

    BRef l'intention de ce code n'est pas mauvaise (utilisation requête préparée) mais dans l'état il ne marche pas.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    mars 2009
    Messages
    2 305
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : mars 2009
    Messages : 2 305
    Points : 5 027
    Points
    5 027
    Par défaut
    Moi je vois une sacrée faille de sécurité, c'est qu'avec un simple préfixe + un code de région:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    switch ($req ['group']) {    
              case 'Assistant':        
                       $pass_std = 'PswAss' .$req ['region'];        
                       break;    
              case 'Agent':        
                       $pass_std = 'Pswagt' .$req ['region'];        
                       break;    
              case 'Responsable':        
                       $pass_std = 'Pswresp' .$req ['region'];        
                       break;
    }
    les mots de passe sont déductibles les uns des autres. L'Assistant pourra facilement avoir le passe du responsable ou celui de l'agent et vice-versa, voire ceux d'un groupe d'une autre région si cette partie n'est pas cryptée (rien n'est précisé à ce sujet).
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

Discussions similaires

  1. Générer un fichier XML à partir php et requête SQL
    Par ramzi87 dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 13/09/2015, 17h22
  2. Syntaxe PHP pour requête SQL
    Par jasinskimathieu dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 29/01/2015, 18h02
  3. [MySQL] Script php avec requête SQL
    Par Thibault85 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 05/06/2014, 11h01
  4. [SQL] Problème PHP et requête SQL
    Par Pepito dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 12/05/2006, 02h41

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