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

Langage PHP Discussion :

Se protéger des $_get


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 257
    Points : 97
    Points
    97
    Par défaut Se protéger des $_get
    Salut à tous,
    je récupère les infos passées dans l'url d'un site par $_SERVER
    et je les mets dans une bd voir ce qui se passe.

    Assez fréquement il y a ce style:

    16:07:11|/index.php?p=accueil.php

    16:07:13|/index.php?p=accueil.php&gyGS=4073%20AND%201%3D1%20UNION%20ALL%20SELECT%201%2CNULL%2C%27%3Cscript%3Ealert

    %28%22XSS%22%29%3C%2Fscript%3E%27%2Ctable_name%20FROM%20information_schema.tables%20WHERE%202%3E1--%2F%2A%2A%2F%3B

    %20EXEC%20xp_cmdshell%28%27cat%20..%2F..%2F..%2Fetc%2Fpasswd%27%29%23

    16:07:14|/index.php?p=accueil.php%22%28%27.%2C%2C..%2C%2C

    16:07:15|/index.php?p=accueil.php%27ePVCmH%3C%27%22%3ELamIUJ

    Donc des information_schema, des passwd et autre cmdshell

    J'ai déjà fait un truc comme:
    - "Si l'url contient les mots delete, update, drop etc... "
    > session_destroy et localStorage.clear();sessionStorage.clear();

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $get=strtolower(strip_tags($_SERVER['QUERY_STRING']));
    if (strstr($get,'delete')||strstr($get,'select')||strstr($get,'update')||strstr($get,'insert')||strstr($get,'drop')||strstr($get,'create')||strstr($get,'execute')) 
    {
        echo 'Désolé, j\'ai piscine';
        session_destroy();
        echo '<script type="text/javascript">localStorage.clear();sessionStorage.clear();</script>';
    }
    Aussi, ca fait beaucoup de mot à tester
    (à chaque rechargement de page).

    En $_GET je passe uniquement
    le nom de la page p et des fois un id
    ex:
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    index.php?p=accueil.php&&id=xx
    Pour info, dans index.php il y a
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    if (!@include($_GET['p'])) {include('home.php');}

    Est-ce qu'on pourrait limiter cette recherche fastidieuse de:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (strstr($get,'delete')||strstr($get,'select') ... ||strstr($get,'execute')) 
    {...}
    en ne cherchant que les $_GET valides
    avec des caractères génériques lorsqu'il y a un &&id=xx?

    Sinon, lister les GET
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (isset($_GET)) {
      foreach ($_GET as $key => $value_get) {
     	// si c'est un pas un get maison 'p' ou 'id'
    	if($key != 'p' || $key != 'id') 
    	{echo 'Merci, bonsoir !';}
      }}
    Et pour les POST, comment pourrait-on les repérer ?

    Merci cavo789 pour aesecuremais c'est un peu chaud à utiliser. https://www.aesecure.com/logiciel/telecharger

    La bise
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait." Mark Twain

  2. #2
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 496
    Points : 12 596
    Points
    12 596

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    il faut arrêter la parano...
    Ça ne sert à rien de barricader sa porte si on laisse une fenêtre ouverte...

    Tu n'as pas besoin de contrôler "tout" ce que contient $_GET, mais juste ce dont tu as besoin.
    Car un bon développeur est censé savoir ce qu'il fait.


    Citation Envoyé par feelwatt Voir le message
    En $_GET je passe uniquement le nom de la page p et des fois un id
    Si tu as besoin de "p" et "id", alors c'est $_GET['p'] et $_GET['id'] qu'il faut vérifier au moment de leur récupération.

    • "id" : à priori, c'est un "numérique"
    • "p" : un nom de page. On peut définir un array des noms acceptables (les pages de ton site), et/ou un pattern à respecter.

    Ainsi, si tu es amené à passer d'autres paramètres (année, numéro de page,... ou autre), il suffira de les vérifier aussi.

    Idem pour $_POST.
    Dernière modification par Invité ; 28/03/2020 à 08h05.

  4. #4
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 257
    Points : 97
    Points
    97
    Par défaut
    Ok, ok
    #MaitrePylos
    Oui, j'utilise htmlspecialchars() pour l'affichage et striptags() pour l'enregistrement en bd.

    #jreaux62,
    ok, pour la parano pardon.
    "id" : à priori, c'est un "numérique"
    "p" : un nom de page. On peut définir un array des noms acceptables (les pages de ton site), et/ou un pattern à respecter.
    Nickel et rapide:
    • id > if (is_numeric())
    • lister un array des pages et voir si le $_GET['p'] en fait partie.


    Merci.

    Ps:
    Pour l'array
    On peut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $dir='nom_dossier';
    if($dir)
    { 
      while ($entry = $dir->read()) { 
        if (strstr($entry,'.php')) {
    	$pages_valides.=$entry.'|';
        }
      } 
    }
    Ca évite d'en oublier.
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait." Mark Twain

  5. #5
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,
    Citation Envoyé par feelwatt Voir le message
    Ok, ok
    #MaitrePylos
    Oui, j'utilise htmlspecialchars() pour l'affichage et striptags() pour l'enregistrement en bd.
    Houlà, surtout pas striptags() pour échapper avant l'enregistrement en base de données. Ça ne sert à rien du tout.
    Chaque moteur de base de données à son propre mécanisme de protection, tu dois l'utiliser : tiens un petit topo par ici, lis la première partie.

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 257
    Points : 97
    Points
    97
    Par défaut
    Ok merci rawsrc
    Houlà, surtout pas striptags() pour échapper avant l'enregistrement en base de données. Ça ne sert à rien du tout.
    Chaque moteur de base de données à son propre mécanisme de protection, tu dois l'utiliser : tiens un petit topo par ici, lis la première partie.
    En effet,
    dans
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    try { 
    	$sql = "UPDATE bdd_name SET col_name=? WHERE id=?";
    	$stmt = $bdd_user->prepare($sql);
    	$stmt->execute(array($valeur,$id));
    } catch(PDOException $e) {$erreur_sql='Erreur: '.$sql.'<br>'.$e->getMessage();}
    J'ai envoyé
    Code js : Sélectionner tout - Visualiser dans une fenêtre à part
    <script type="text/javascript">alert('boum');</script>
    et il ne reste que
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait." Mark Twain

  7. #7
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    tu peux envoyer ce que tu veux à la base comme au navigateur à condition de toujours échapper correctement les données :
    - pour la base de données, c'est souvent via le mécanisme de préparation : $stmt = $pdo->prepare($sql);,
    - pour l'affichage, c'est toujours avec htmlspecialchars().

    Ainsi tu rends les données saisies par un utilisateur inoffensives quel que soit le contexte dans lequel tu évolues (base de données et/ou affichage html)

    Tu peux très bien sauvegarder en base de données la chaîne complète saisie telle quelle par l'utilisateur : <script type="text/javascript">alert('boum');</script>, tu peux aussi la renvoyer telle quelle au navigateur À CONDITION DE L'ÉCHAPPER CORRECTEMENT : echo htmlspecialchars('<script type="text/javascript">alert("boum");</script>', ENT_QUOTES, 'utf-8');

  8. #8
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 257
    Points : 97
    Points
    97
    Par défaut
    J'ai du me planter
    j'ai donc envoyé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <script type="text/javascript">alert('boum');</script>
    Dans
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    try { $sql = "UPDATE db_name SET colonne=? WHERE id=?";
    $stmt = $bdd_user->prepare($sql);
    $stmt->execute(array($_POST['new_valeur'], $_POST['id'])));
    } catch(PDOException $e) 
    {$erreur_sql='Erreur: '.$sql.' <br>'.$e->getMessage();}
    Sans strip_tags à l'enregistrement
    et à l'affichage
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    <?php echo htmlspecialchars($results['colonne'], ENT_QUOTES, 'utf-8');?>
    Ca fait boum.

    Avec strip_tags ca enregistre alert('boum');

    Par contre écrire dans la page
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
     echo htmlspecialchars('<script type="text/javascript">alert("boum");</script>', ENT_QUOTES, 'utf-8');
    ca fait pas boum.
    Je croire que je me perd qql part...
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait." Mark Twain

  9. #9
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    ta base de données est encodée utf-8 ? Est-ce qu'à l'ouverture de connexion tu définis le bon charset ?

  10. #10
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 257
    Points : 97
    Points
    97
    Par défaut
    Salut,

    Pour la page l'encodage est:
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    Pour les BD c'estet à l'ouverture de connexion:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    try
    {	
    	$bdd_user = new PDO("mysql:host=localhost;dbname=db_name", "root", "");
    	$bdd_user->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
    catch(Exception $e)
    	{
    	die('Erreur connect bd: '.$e->getMessage());
    }
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait." Mark Twain

  11. #11
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    avec les encodages c'est hyper simple : tu dois être homogène sur toute la ligne. A chaque étape/niveau tu dois avoir le même encodage.

    Tiens un peu de lecture par ici.

    Si ta base est vide, je te conseille de redéfinir tous les encodages et collations (base, tables) en utf-8
    Si elle ne l'est pas, tu vas être obligé d'y aller à coup d'ALTER après avoir bien tout sauvegardé (surtout !)

  12. #12
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 257
    Points : 97
    Points
    97
    Par défaut
    Ok, va falloir tout remettre,
    j'avais récupéré cette base et elle est en latin1_swedish_ci
    Si elle ne l'est pas, tu vas être obligé d'y aller à coup d'ALTER après avoir bien tout sauvegardé (surtout !)
    Je vais tenter de faire une boucle sur les tables.
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait." Mark Twain

  13. #13
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 257
    Points : 97
    Points
    97
    Par défaut
    Ok je fais le tour des tables avec
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?php 
      $bd_name='a3u12e';
      $req = $bdd_user->prepare("SHOW TABLES FROM $bd_name");
      $req->execute(array());
      while ($results=$req->fetch()) { 
        // print_r($results);
        $table_name=$results[0];
        echo $table_name;
        echo '<hr>';
      } ?>
    J'ai un souci pour y insérer la boucle pour faire le tour des colonnes
    Code php : 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
    <?php 
      $bd_name='a3u12e';
      $req = $bdd_user->prepare("SHOW TABLES FROM $bd_name");
      $req->execute(array());
      while ($results=$req->fetch()) { 
        // print_r($results);
        $table_name=$results[0];
        echo $table_name;
     
        // *** Tour des colonnes
              $i=0;
              $sql = "SELECT column_name FROM information_schema.columns WHERE table_name = $table_name AND table_schema=$bd_name";
              echo $sql.'<br>';
              $req_colonnes = $bdd_user->query($sql);
                while ($colonnes = $req_colonnes->fetch(PDO::FETCH_ASSOC))
                { 
                  echo $i." => '".$colonnes['column_name']."', ";
                  $i++;
                }
        // *** Tour des colonnes
     
        echo '<hr>';
      } ?>
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait." Mark Twain

  14. #14
    Membre régulier
    Homme Profil pro
    Inscrit en
    Février 2012
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 257
    Points : 97
    Points
    97
    Par défaut
    Ok,
    Je comprends je sors du sujet de départ.
    Résolu, merci.
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait." Mark Twain

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

Discussions similaires

  1. Protéger des échantillons de musique
    Par unreal2me dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 15/04/2007, 12h15
  2. [Conception] Protéger des données payantes
    Par Denti-fritz dans le forum Langage
    Réponses: 10
    Dernier message: 06/02/2007, 09h51
  3. se protéger des trojan
    Par lastrecrue dans le forum Sécurité
    Réponses: 5
    Dernier message: 07/08/2006, 10h35
  4. [PHP-JS] Protéger des pages php
    Par Kiboumz dans le forum Langage
    Réponses: 5
    Dernier message: 12/07/2006, 10h21
  5. Protéger des images
    Par duplo dans le forum Apache
    Réponses: 13
    Dernier message: 29/12/2005, 20h38

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