Comme ça fait un bon bout de temps que j’aurais du écrire cet épisode, je me rattrape en faisant un gros épisode totalement dédié à la sécurité. Je ne parlerait que des failles XSS et des injections SQL, donc inutile de vous attendre à découvrir des failles que vous ne connaissiez pas.

Il y a pas mal de fonctions pour se sécuriser contres les attaques les plus courantes : les injections SQL et les attaques XSS.

Les injections SQL ont lieux lors d’une requête SQL (quel surprise :p ). Cette attaque consiste à insérer du code SQL indésirable dans une requête que vous faites pour la détourner.

Les failles XSS ont lieux quand on affiche des donnés venant d’un utilisateur. Cette attaque consiste à rajouter de l’xHTML et du javascript dans une page pour récupérer des donnés sur les autres utilisateurs afin d’accéder à leur comptes facilement ou de leur faire faire ce que l’on veut.

Pour palier à ces attaques, il existe beaucoup de fonctions. Je vais vous présenter les plus connus.

htmlspecialchars

Sous ce nom barbare se cache une fonction très pratique qui va transformer tous les caractères spéciaux d’xHTML (à savoir <, >, & et ") en leurs équivalents échappés : respectivement &lt; &gt; &amp; et &quot;
Un petit exemple :

<?php

$pseudo 
'Pindel >.<';        

$pseudo htmlspecialchars($pseudo); // renvoie  Pindel >.<

echo $pseudo;                        // affiche  Pindel >.<

?>


Les débuts et fin de balises ne seront donc pas interprétés. Un utilisateur malveillant ne pourra pas insérer de javascript, on est donc tranquille.

Voici la page de la doc si vous voulez plus de détails : htmlspecialchars()

htmlentities

Cette fonction fait un peu la même chose que htmlspecialchars, sauf qu’elle transforme en leurs équivalents xHTML un maximum de caractères.
Si vous voulez la liste des caractères qui sont convertis pas htmlentities, faites :
print_r(get_html_translation_table(HTML_ENTITIES));

Petit exemple :


<?php

$pseudo 
'The killer>©';         

$pseudo htmlentities($pseudo); // renvoie  The killer&gt;&Acirc;&copy;

echo $pseudo;                    // affiche  The killer>©

?>

Voici la page de la doc : htmlentities()

mysql_real_ecape_string

Cette fonction va échapper les caractères spéciaux d’une chaine afin de pouvoir l’insérer dans une requête sans risque.
Les caractères échappés (par un backslash) sont :

Caractère Signification
NULL chaine vide
\x00 fin de chaine
\n fin de ligne
\r retour à la ligne
\ caractère d’échappement
début/fin de chaine en SQL (échappé par une autre apostrophes si magic_quotes_sybase est activé)
" début/fin de chaine en SQL
\x1a Caractère de contrôle ASCII (substitution)

C’est quoi magic_quotes_sybase? o_O

C’est une directive qui permet de définir si les apostrophes sont échappés par une autre apostrophe (syntaxe du SQL) ou par un backslash.
Un petit exemple pour cette fonction (avec magic_quotes_sybase activé) :


<?php

$pseudo 
"O'neil";

$pseudo mysql_real_escape_string($pseudo); // renvoie O''neil

mysql_query("INSERT INTO personnages(pseudo, mdp, mail)
 VALUES('$pseudo', '$mdp', '$mail')"
);

?>

La requête protégé va donc être :
INSERT INTO personnages(pseudo, mdp, mail) VALUES(‘O”neil’, ‘pà_Au68′, ‘lorem_ipsum@dolor.sit’)

Et la requête non protégé :
INSERT INTO personnages(pseudo, mdp, mail) VALUES(‘O’neil’, ‘pà_Au68′, ‘lorem_ipsum@dolor.sit’)

On vois bien que la première chaine de caractère s’arrête trop tôt.
On peut noter qu’il faut être connecté à MySQL pour pouvoir utiliser cette fonction.

La page de la doc est ici : mysql_real_escape_string()

Addslashes

Cette fonction se contente de rajouter des backslashes sur les quatre caractères les plus utiliser pour faire une injection SQL : NULL, , " et \. Elle est donc moins sécurisé que celle que l’on vient de voir (mysql_real_escape_string). Elle est aussi affecté par la constante magic_quotes_sybase (voir juste au-dessus).
Cette fois-ci, je met pas d’exemple, je pense que vous avez compris.
Il faut quand même noter qu’il est mieux d’utiliser mysql_real_escape_string pour protéger ses requêtes SQL.

Il existe aussi une fonction nommée addcslashes qui permet de choisir les caractères qui seront échappés.
Il existe aussi une fonction contraire qui permet d’enlever l’échappement des caractères échappés : stripslashes pour addslashes et stripcslashes pour addcslashes.

Et les liens vers les pages de la doc : addslashes(), stripslashes(), addcslashes() et addslashes().

Magic_quote_gpc

Ceci n’est pas une fonction à proprement parlé, mais une directive. Pour résumer, une directive est un élément de configuration qui va modifier le comportement de PHP. Je vous ai déjà parlé de magic_quotes_sybase qui permet d’échapper les apostrophe avec une autre apostrophe plutôt qu’avec un backslash. magic_quotes_sybase modifie donc le comportement des certaines fonctions.

magic_quote_gpc permet, elle d’appeler avant d’analyser le PHP d’appeler addslashes sur les variables super globales $_GET, $_POST et $_COOKIE (d’où le GPC).
Elle est activé par défaut, sauf avec PHP 6 où elle à été supprimée.

Cette directive est obsolète depuis PHP 5, il ne faut donc plus compter sur elle!
En fait, si je vous en parle, c’est qu’elle est activé par défaut sur la plus part des servers.
D’ailleurs, je ne vais pas vous détailler en détail comment les désactiver, donc je vous redirige vers ce tutoriel qui en parle : Les magic quotes ou guillemets magiques.

Et la suite est pour bientôt :)

3 commentaires

  • Dimitri (6 comments), le 29 octobre 2009

    Il ne faut plus utiliser addslashes(), cette fonction est faillible. La combinaison idéale est :

    $var = mysql_real_escape_string($var);
    $var = addcslashes($var, ‘%_’);

    addcslashes() permettant d’échapper certains caractères utilisés lors de requêtes avec LIKE et qui ne sont pas échappés par mysql_real_escape_string().

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

    Je n’ai jamais dit qu’il fallait utiliser addslashes() mais que c’était une fonction utilisé pour la sécurité.
    Mais par contre, échapper les % et _ n’est utile que dans le cas d’une chaine inséré dans une recherche avec LIKE. Dans les autres cas, il ne faut pas le faire.

  • Dimitri (6 comments), le 30 octobre 2009

    Tout à fait mais je pense qu’il aurait fallu insister sur le fait de ne plus utiliser cette fonction obsolète.

Poster un commentaire

Subscribe without commenting