Trop de vérifications ?

Eléphant du PHP | 65 Messages

05 juil. 2016, 10:44

Bonjour à tous,
Une question me turlupine, je vois beaucoup de tutos sur le web avec des tonnes de vérifications lorsqu'il s'agit de récupérer des données entrées par l'utilisateur. On fait du preg_match, du stripslashes, du mysql_real_escape_string, etc. Alors qu'en principe, un simple preg_match suffit.
Par exemple :

Code : Tout sélectionner

if (preg_match('#^[a-z]{3,10}$#i', $nom)): // Instructions endif;
Si l'utilisateur rentre autre chose que ce que j'ai défini dans la RegEx, ça ne passe pas.

Pouvez-vous m'expliquer ? Ils en font trop ou il y a un danger que je ne perçois pas ?

Mammouth du PHP | 2703 Messages

05 juil. 2016, 12:54

ils en font plus que nécessaire.
mieux vaux faire systématiquement certaines choses, même superflues, que les oublier une fois et de laisser une faille dans son code.

ViPHP
ViPHP | 928 Messages

05 juil. 2016, 13:38

Normalement stripslashes() tu n'es plus censé en croiser aujourd'hui, ça fait un baille que les magic_quotes sont au mieux dépréciés.

Concernant mysql_real_escape_string() c'est à mon sens indispensable dans toutes les requêtes SQL à l'ancienne pour être certain de ne pas se prendre une injection SQL.

A part ça, une simple regexp suffit effectivement généralement, encore faut il bien la maîtriser.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

05 juil. 2016, 14:09

salut

L'utilisation d’expression régulière peux être est plus coûteuse que quelque vérification supplémentaire.
Ton exemple impose entre 3 et 10 caractères alphébtique. comment font le gens qui ont un nom qui fait plus de 10 caractères (c'est courant, et je ne parle pas des noms à particule ou avec apostrophe) ?

il y a des données que l'on peux vérifier ainsi car ont est sur du format mais ce n'est pas toujours le cas.

ensuite comme indiqué il s'ait surement de code relativement vieux et effectivement pas toujours réalisé de façon logique.
Par exemple une mysql_real_escape_string est inutile sur un entier (il valider un entier avant bien sur).

Si tu es dans le cas où la donnée peux être validée par une expression régulière et que celle ci ne contient pas de caractère qui peuvent être interprété par le SGBD (notamment l’apostrophe) alors oui tu peux n'utiliser que l'expression régulière, mais dans les cas tu devras passer par la case mysql(i)_real_escape_string ou quote avec PDO. alors oui les requêtes préparées échappent aussi les données mais autant utiliser les chose pour lequelles elle sont faites. C'est d'ailleurs en grand partie a cause de cela que les "gens" ont tendances à ne plus vérifier les données avant de l'employer.

bref : c'est utile et non super flux suivant les cas d'usages.

rebref : ça dépends :mrgreen: :mrgreen: :mrgreen:

@+
Il en faut peu pour être heureux ......

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

05 juil. 2016, 14:40

A noter l’existence de filter_var() qui peut faire gagner beaucoup de temps et avec ses filtres prédéfini rend la relecture du code bcp + simple.
http://php.net/filter_var
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphant du PHP | 65 Messages

07 juil. 2016, 10:44

En fait c'est surtout qu'à voir toutes ces vérifications cumulées je me perds et ne vois plus la cohérence, par exemple - dites moi si je me trompe - mais dans le cas d'une requête préparée mysql_real_escape_string est inutile, il est en revanche indispensable dans le cas d'une requête "normale" afin d'éviter les injections.

Aussi, lorsqu'il s'agit d'afficher un résultat avec htmlspecialchars, je ne comprends pas pourquoi dans de nombreux tutos que je lis ils appellent la fonction à chaque affichage alors qu'il suffirait de l'appeler une fois lors de la création de l'objet / de la variable et ne plus s'en soucier.

N'y voyez pas une quelconque prétention j'essaye juste d'optimiser ma façon de programmer pour partir sur des bases solides.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

08 juil. 2016, 12:23

Bonjour,

Effectivement, lorsque tu utilises les requêtes préparées, les variables que tu passes par binding sont automatiquement protégées, il ne faut donc pas cumuler avec mysql_real_escape_string ou pdo::quote. En revanche, il faut absolument protéger les variables si tu passes par les requêtes classiques. Ce contrôle ne sert que si la variable est insérée en base. Si elle doit aller en session ou dans un fichier, ces protections ne sont pas nécessaires (d'autres en revanches peuvent être requises).

Pour ce qui est de l'appel de htmlspecialchars à l'affichage, plutôt qu'à l'enregistrement, il y peut y avoir plusieurs raison à ce choix. La première est que l'information en base n'est pas nécessairement destinée à de l'affichage web. L'impression pdf ou la génération de fichier d'exports pourront nécessiter de voir apparaitre le texte tel qu'il a été saisi plutôt que transformé avec des entités html. La seconde est de faciliter l'édition de la valeur saisie, là encore il est plus intéressant de proposer le texte d'origine que la valeur transformée.

Ce genre de choix dépend donc de l'usage que tu fais de la valeur enregistrée Vs les performances. C'est un peu le même principe que pour des indexes en bases de données : ils accélèrent les SELECT mais ralentissent les INSERT/UPDATE. Si ta base est d'avantage consultée que mise à jour, on mets des indexes, si elle est plus souvent mise à jour que consulter, on gagne en performance à ne pas en mettre :)

La chose la plus importante à retenir est qu'il ne faut jamais faire confiance à l'utilisateur et toujours contrôler les données reçues côté serveur. Si tu attends un chiffre, c'est un chiffre que tu dois recevoir, sinon c'est une faille et un pirate pourrait l'exploiter. Si un champ est désactivé mais que tu reçois quand même une valeur pour ce champ, c'est un pirate. Si les captcha ne sont pas corrects, c'est un pirate. S'il coche pas la case de recaptcha, c'est un pirate. S'il manque des champs, c'est un pirate. S'il y a des infos que tu n'attends pas, c'est un pirate... Si tout est parfait, c'est quand même un pirate, faut recontrôler ! ;)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...