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 :

Filtrer les variables


Sujet :

Langage PHP

  1. #1
    Membre à l'essai
    Homme Profil pro
    Webmaster
    Inscrit en
    Janvier 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Janvier 2016
    Messages : 12
    Points : 15
    Points
    15
    Par défaut Filtrer les variables
    Bonjour,

    Pour sécuriser les données que mes visiteurs envoient j'utilise la preg ci-dessous pour filtrer (pas les valider) leurs variables :

    Pour les emails :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $email = preg_replace("#[^0-9a-zA-Z@._\-]#","",strtolower($_POST['email']));
    Pour les variable alpha numérique avec accent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $prenom=preg_replace("#[^0-9a-zA-Z-_.!?;:ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ ']#","",$_POST['prenom']);
    Et par exemple avec un GET qui est sensé avoir que des chiffres je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $chiffre=preg_replace("#[^0-9]#","",$_GET['chiffre']);
    Ca fonctionne bien.
    Ma question est la suivante : est-ce qu'il y a un moyen plus léger en resource CPU pour faire la même chose que scanner la variable entière avec un preg_replace ?

  2. #2
    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 : 48
    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,

    Holàààà ! Halte-là ! Démarre donc bien l'année 2016 s'il te plait et va lire la doc de la fonction filter_var() qui va pour le coup devenir ta meilleure amie

  3. #3
    Membre à l'essai
    Homme Profil pro
    Webmaster
    Inscrit en
    Janvier 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Janvier 2016
    Messages : 12
    Points : 15
    Points
    15
    Par défaut
    Bonjour,

    Merci pour la réponse.
    Effectivement je viens de voir qu'il y a un filtre FILTER_SANITIZE_EMAIL donc ca déjà c'est génial merci !

    Par contre je vois rien pour l'aphanumérique avec accent, y a même rien pour l'alpha numérique tout court, c'est dommage je trouve.
    Du coup pour filtrer les variable de type prénom obligé de faire du preg ?

  4. #4
    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 : 48
    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
    Pour l'alphanumérique : ctype_alnum()
    Après pour ce qui est des accents, tu peux faire effectivement du regex, mais il est aussi possible de remplacer tous les caractères spéciaux par une chaîne vide (str_replace) et vérifier que ce qui reste correspond à de l'alphanumérique. Si le test renvoie false alors c'est qu'il reste des caractères exotiques.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Webmaster
    Inscrit en
    Janvier 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Janvier 2016
    Messages : 12
    Points : 15
    Points
    15
    Par défaut
    Bon j'ai fais un test rapide avec le code ci-dessous si ca intéresse quelqu'un, systèmatiquement FILTER_SANITIZE_EMAIL est plus rapide à exécuté que le preg_replace, donc ca c'est une bonne nouvelle

    La mauvaise nouvelle c'est que FILTER_SANITIZE_EMAIL accepte des caractères qui sont quasiment ( pour pas dire jamais ) utilisé dans un email, je suppose que ca suit une norme RFC quelconque, mais par exemple ca accepte !#$%&'*+-=?^_`{|}~@.[] , perso je considère que quelqu'un qui mets un ! ou un # dans son adresse email a un gros doigt et à fait une faute de frappe, et je parle même pas de { }

    En plus de ca t'as de grande chance que si t'utilise cet email ca n'arrive jamais à son destinataire. C'est a mon humble avis une très mauvaise idée d'accepter qu'un visiteur ajoute des ! ou des ^ dans son adresse email.

    C'est dommage parce que sur le papier c'est génial FILTER_SANITIZE_EMAIL mais c'est inutilisable je trouve !

    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
    $email_bidon="sds!/dsd@sdsosdosdoisdisdoo010928129812981928198298128982mpdoILKID1ù^$*ù^$!:mloKIUZEEZZEEZZEEZEZZEdsd.c om)";
     
    $timestart=microtime(true);
    $email=strtolower(filter_var($email_bidon, FILTER_SANITIZE_EMAIL));
    $timeend=microtime(true);
    $time=$timeend-$timestart;
    $page_load_time1 = number_format($time, 15);
     
    echo "$email <br>$page_load_time";
    echo"<br><br><br><br><br><br><br>";
     
     
    $timestart=microtime(true);
    $email = preg_replace("#[^0-9a-zA-Z@._\-]#","",strtolower($email_bidon));
    $timeend=microtime(true);
    $time=$timeend-$timestart;
    $page_load_time2 = number_format($time, 15);
     
    echo "$email<br> $page_load_time";
    echo"<br><br><br><br><br><br><br>";
     
     
    if($page_load_time2>$page_load_time1)
    {
    	echo"preg_replace plus long";
    }
    else
    {
    	echo"filter_var plus long";
    }

  6. #6
    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 : 48
    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, pour les emails, il me semble que la norme c'est la RFC 822

  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 : 48
    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
    Pour valider les email, tu as ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $is_valid = filter_var("sds!/dsd@sdsosdosdoisdisdoo010928129812981928198298128982mpdoILKID1ù^$*ù^$!:mloKIUZEEZZEEZZEEZEZZEdsd.c om)", FILTER_VALIDATE_EMAIL); // false

  8. #8
    Membre à l'essai
    Homme Profil pro
    Webmaster
    Inscrit en
    Janvier 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Janvier 2016
    Messages : 12
    Points : 15
    Points
    15
    Par défaut
    Rebonjour,

    Si je comprend bien la doc :
    FILTER_SANITIZE_EMAIL : Supprime tous les caractères sauf les lettres, chiffres, et !#$%&'*+-=?^_`{|}~@.[]
    Ca voudrais dire que FILTER_SANITIZE_EMAIL protége des attaque XSS par exemple, et d'une manière général ca nettoie bien une variable utilisateur assez simplement.

    Est-ce que l'on pourrais pas utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $var = filter_var($_POST['var'], FILTER_SANITIZE_EMAIL);
    pour protéger simplement la plupart des variables qui viens d'un post (sauf les variables avec accent ou espace) ?


    Est-ce que je me trompe ?

  9. #9
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Mauvaise idée. Tu confonds filtrer et échapper. Ils peuvent sembler similaires (ex FILTER_SANITIZE_FULL_SPECIAL_CHARS et htmlspecialchars) mais correspondent à des cas d'utilisations différentes.

    Filtrer et valider veut dire que tu as un format que tu acceptes (email, téléphone, code postal etc...) et tu rejettes ou transforme toutes les données externes qui ne correspondent pas à ce format. Point. Un filtre ne sécurise pas ton code, il a pour but d'éviter que l'utilisateur t'envoie des données inutilisables.

    Échapper consiste à transformer une variable en fonction d'un contexte pour des raisons de sécurité. L'échappement est donc en fonction du contexte: tu n'échappes pas de la même manière selon que ta variable est envoyée dans une base de donnée, affichée dans une balise html, insérée dans du javascript, du CSS, un champ header ou utilisée en tant que chemin de fichier.

    Donc:

    1) Tu ne peux donc pas utiliser un filtre, qui n'a pas de contexe, à la place d'un échappement.
    2) Le filtrage/la validation s'effectue à l'arrivée de la variable, alors que tu dois échapper au tout dernier moment, quand tu es sûr du contexte dans lequel tu vas utiliser la variable. Imaginons que tu utilises FILTER_SANITIZE_FULL_SPECIAL_CHARS comme flag pour tes filtres et que tu enregistres ensuite tes données dans ta base. Ça ne va pas te protéger d'une injection SQL, d'une injection json, d'une injection CSS, d'une injection de fichier, d'une attaque par path traversal, d'un empoisonnement des headers, des cookies, de unserialize() etc etc. Seule un échappement en fonction du contexte te garantit ça.

    Conclusion: il faut utiliser les deux, et ne pas méprendre l'un pour l'autre.

  10. #10
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Quand aux critères de validation d'un email, il faut faire attention parce que certains caractères qu'on peut ne pas considérer "normales" au premier abord sont en fait utilisées par un certain nombre de gens. Par exemple, un certain nombre de fournisseurs d'email (gmail, hotmail par exemple) permettent la création d'alias illimités en utilisant les caractères "+" ou ".". En rejetant ces caractères (ou pire, en les transformant), tu ferais une grave erreur (que beaucoup de regex pour emails font). Et je suis sûr qu'il y a d'autres caractères tout aussi fréquemment utilisés.

    Au final, tu risques de faire comme certains sites anglophones d'il y a quelques années, qui rejetaient (ou transformaient) les noms à accents parce que les accents n'était jamais utilisés chez eux.

  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 : 39
    Localisation : France

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Au passage, si tu veux tester/filtrer des données provenant d'un formulaire/url, tu peux utiliser filter_​input à la place de filter_var.
    En plus du filtre, ça vérifie que la variable existe bien,ce qui évite d'avoir à ajouter des isset() un peu partout (ou les notice Undefined Index )

  12. #12
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2007
    Messages
    748
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 748
    Points : 1 022
    Points
    1 022
    Par défaut Un peu des 2
    je serais presque à proposer cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <?php
    $email_bidon = strtolower("sds!/dsd@sdsosdosdoisdisdoo010928129812981928198298128982mpdoILKID1ù^$*ù^$!:mloKIUZEEZZEEZZEEZEZZEdsd.c om)");
     
    $is_valid = filter_var($email_bidon, FILTER_VALIDATE_EMAIL) && filter_var($email_bidon, FILTER_SANITIZE_EMAIL) === $email_bidon ? true : false;
    on confirme que l'email match le filtre, et on confirme que le sanitize ne transforme pas l'email.

    (même si je me dit que les filtres sont un peu les même )

  13. #13
    Membre à l'essai
    Homme Profil pro
    Webmaster
    Inscrit en
    Janvier 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Janvier 2016
    Messages : 12
    Points : 15
    Points
    15
    Par défaut
    Citation Envoyé par Tsilefy Voir le message
    Mauvaise idée. Tu confonds filtrer et échapper. Ils peuvent sembler similaires (ex FILTER_SANITIZE_FULL_SPECIAL_CHARS et htmlspecialchars) mais correspondent à des cas d'utilisations différentes.
    Bonjour à tous et merci pour vos réponses,

    J'ai relus plusieurs fois votre message, pour essayer de ne pas dire de bétise.
    Ce que je cherche avant tout c'est protéger mes variable post et get de quelqu'un de mal intentionné, je ne cherche pas à les valider, la dessus j'ai bien compris la différence.

    Après ca se complique, peut être que je m'exprime mal ou peut être que j'utilise les mauvais terme.
    Ce que je voulais dire c'est détourner ces filtres pour s'en servir comme liste blanche et éviter de faire des preg_replace qui sont lent, exemple :

    $chiffre = filter_var($_POST['chiffre'], FILTER_SANITIZE_NUMBER_INT);
    Imaginons que vous attendez que des chiffres de cette variable $_POST['chiffre']
    Peut-on considérer que le filtre FILTER_SANITIZE_NUMBER_INT (qui supprime tout sauf les chiffres) se comporte comme une liste blanche, et protège cette variable des xss, injection etc ?
    Si quelqu'un ajoute par exemple un ' ou un < ou je ne sais quelle autre cochonnerie dans cette variable cela va être effacén ca reviens donc au final à protéger cette variable non ?

  14. #14
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Citation Envoyé par Zachatim Voir le message

    Ce que je voulais dire c'est détourner ces filtres pour s'en servir comme liste blanche et éviter de faire des preg_replace qui sont lent, exemple :

    Imaginons que vous attendez que des chiffres de cette variable $_POST['chiffre']
    Peut-on considérer que le filtre FILTER_SANITIZE_NUMBER_INT (qui supprime tout sauf les chiffres) se comporte comme une liste blanche, et protège cette variable des xss, injection etc ?
    Si quelqu'un ajoute par exemple un ' ou un < ou je ne sais quelle autre cochonnerie dans cette variable cela va être effacén ca reviens donc au final à protéger cette variable non ?
    - Oui, un filtre est une liste blanche et te permets d'éliminer des valeurs inacceptables

    - Non, un filtre n'est jamais suffisant pour te protéger. Tu dois te protéger contre "quelque chose" (injection SQL, XSS, injection de code etc...), c'est-à-dire un "contexte", et pour te protéger efficacement tu dois savoir quel est ce contexte et utiliser la fonction qui correspond à ce contexte (htmlspecialchars pour XSS dans un HTML, json_encode pour XSS dans un javascript, requête préparée pour mysql, basename et realpath pour une directory/path traversal, etc...).

    Donc, tu dois filtrer ta variable juste après la soumission du formulaire mais ce n'est pas suffisant. Il faut ensuite l'échapper:
    - au moment d'enregistrer l'email dans la base de données, il faut utiliser une requête préparée.
    - Au moment d'afficher l'email sur une page HTML (que ce soit directement ou en l'ayant récupéré de la base de données), il faut faire echo htmlspecialchars($email, ENT_QUOTES);
    - et ainsi de suite.

    Bref, tu ne peux pas te contenter de filtrer, tu dois aussi échapper au moment d'utiliser la valeur (çad au moment de l'insérer dans la base, de l'afficher dans une page, de le stocker dans une cookie, etc...).
    Le principe est: Filtrer au début, Échapper à la fin.

Discussions similaires

  1. Réponses: 3
    Dernier message: 07/05/2006, 00h07
  2. peut on filtrer les adresses IP ?
    Par travail dans le forum 4D
    Réponses: 2
    Dernier message: 04/06/2003, 15h16
  3. [syntaxe] Gerer les variables dans une requete
    Par rastapopulos dans le forum MS SQL Server
    Réponses: 12
    Dernier message: 15/04/2003, 13h53
  4. [XSLT] les variables???
    Par Lydiane dans le forum XSL/XSLT/XPATH
    Réponses: 11
    Dernier message: 09/08/2002, 17h17
  5. les variables globales static
    Par gRRosminet dans le forum C
    Réponses: 8
    Dernier message: 27/04/2002, 09h34

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