Comme promis, ce cinquième épisode arrive rapidement (ou pas, je suis vraiment désolé du retard)

Dans l’épisode précédent Meilleur pratique du PHP – Episode 4, nous avons vu les principales fonctions utiles pour assurer la sécurité de son site. Ici, nous allons voir comment et où les utiliser (ben, oui, ça peut être utile :P ).

Les variable utilisées seulement pour un traitement

C’est le cas le plus simple, étant donné qu’il n’y a pas besoin de protéger (de manière courante) les variables que vous utilisez seulement pour les traitements.
Par exemple :
On en a juste besoin pour les traitements :

<?php
if($_GET['pseudo'] == 'Administrateur')
echo
'Vous pouvez supprimer ce topic';
else
echo
'Vous ne pouvez pas supprimer ce topic';
?>

Une chose à ne surtout pas faire (car on affiche le pseudo sans le protéger) :


<?php
if (isset($_GET['pseudo']))
echo
'Bonjour, '.$_GET['pseudo'];
else
echo
'Bonjour, invité';
?>

Ce cas se résume très facilement : il est inutile de sécuriser les variables si elle ne sont ni affichés, ni utilisé dans une requête SQL.

Affichage des variables

Ce n’est pas beaucoup plus compliqué étant donné qu’il ne s’applique que à l’affichage des variable. La fonction de sécurité à utiliser ici est htmlspecialchars. Autre chose : il faut sécuriser ses variable juste avant l’affichage et pas 50 ans avant, sinon, ça risque de poser des problèmes dans les traitements. Idéalement, il faudrait le mettre juste dans le echo.
Un exemple valide :


<?php
if (isset($_GET['pseudo']))
echo
'Bonjour, '.htmlspecialchars($_GET['pseudo']);
else
echo
'Bonjour, invité';
?>

Un exemple à éviter :


<?php
$mail
= htmlspecialchars($_GET['mail']);
if (
mail_valide($mail))
echo 'Votre adresse mail : '.$mail;
else
echo
'Votre adresse mail n\'est pas valide';
?>

Cette exemple est peut-être sécurisé, mais on est pas sûr que la fonction mail_valide va bien évaluer l’adresse mail, vu que si il y a un caractère convertie par htmlspecialchars dans l’adresse mail, la regex va se retrouver avec un adresse mail avec des & et des ; et elle va pas apprécier :-°

Résumé : il faut utiliser htmlspecialchars uniquement quand on affiche une variable qui vient de l’utilisateur et dans aucun autre cas. Il faut l’utiliser juste avant de l’afficher.

Requêtes SQL

Les chiffres

Si vous stockez un chiffre dans la BDD, il suffit d’indiquer à PHP que l’on ne veut récupérer que les chiffres de ce qu’envoie l’utilisateur. Pour cela, il faut utiliser la fonction intval(). Elle va retourner un chiffre inoffensif.

Voici un petit exemple :


<?php
$age
= intval($_POST['age']);
mysql_query("INSERT INTO moyenne_age(age) VALUES($age)");
?>

Les chaines de caractères

Dans ce cas, il faut utiliser mysql_real_escape_string.
Exemple :


<?php
$pseudo
= mysql_real_escape_string($_POST['pseudo']);
mysql_query("INSERT INTO perso(pseudo) VALUES('$pseudo')");
?>

En résumé : La fonction n’est à utiliser que pour les requêtes SQL. Il faut l’utiliser pour du texte que l’on veut insérer dans une requête. Pour les chiffres, il faut utiliser intger().

5 commentaires

  • Dimitri (6 comments), le 29 octobre 2009

    Pour ce qui est de l’utilisation de la fonction intval() avant une requête sql, il est préférable d’utiliser un ‘cast’.

    $var = (int) $_POST['var'];

    Cette méthode est plus optimisée qu’un intval(). Elle renvoie 0 lorsque la variable est une chaîne de caractères.

  • Bloody Vengeance (33 comments), le 29 octobre 2009

    (int)$variable et intval($variable) font EXACTEMENT la même chose. Et d’ailleurs ça ne renvoie pas 0 si c’est une chaine de caractère, mais seulement si la chaine ne commence pas pas un chiffre.
    http://www.php.net/manual/en/language.types.string.php#language.types.string.conversion

    Et au niveau de l’optimisation, en effet, c’est plus rapide de 0.002 secondes sur 10000 itérations. Ce qui veut dire que ça ne changera rien au temps d’exécution des pages.

  • Dimitri (6 comments), le 30 octobre 2009

    Je trouve vos articles sur les bonnes pratiques en php très intéressants. Je tiens à dire que je ne voulais en aucun cas remettre en cause votre travail qui est d’une grande qualité.

    Oui (int) $var et intval($var) font exactement la même mais je pense que cette méthode alternative (transtypage ou cast) peut être utile dans certains cas.

    Utiliser un (int) à la place d’un intval() rend le code plus clair [à mon sens].

    Je n’ai jamais fait confiance à ce genre de tests qui ne sont pas réellement fiables (très “subjectifs”) mais il est vrai qu’en pratique utiliser (int) à la place de intval() ne jouera pas sur le temps d’exécution de la page.

  • Kenshin (1 comments), le 18 décembre 2009

    Pour int est intval c’est exactement pareil comme le dit BloodyVengeance, c’est juste à choisir en fonction des préférences de chacun.
    @BloodyVengeance : par contre, intval() renvoie bien 0 si c’est une chaine de caractères, teste echo intval(’23ZER’); //0

    Sinon le reste est vraiment pas mal, à par peut être le if($_GET['pseudo'] == ‘Administrateur’)
    qui pourrait donner de mauvaises idées si utilisé autrement que pour un simple texte ;)

  • Bloody Vengeance (33 comments), le 18 décembre 2009

    Je sait pas quel version de PHP tu utilise, mais chez moi, var_dump(intval(’23ZER’)); me donne bien int(23) ;)
    Regarde la documentation : http://www.php.net/manual/fr/language.types.string.php#language.types.string.conversion
    C’est bien le comportement indiqué ;)

Poster un commentaire

Subscribe without commenting