htmlspecialchars vides, mysql_ à mysqli_, etc.

Ca y est, la branche 5.3 de PHP est arrivée à terme, avec la sortie le 14 août 2014 de la release 5.3.29, la dernière donc. Les hébergeurs devraient ainsi désactiver cette version dans les prochains mois, faute de mises à jour et donc de risques pour la sécurité. Si vos sites tournent encore sous cette version, il est peut-être grand temps de mettre à jour vos pages car quelques changements majeurs ont été apportés sur les versions 5.4 et 5.5. En voici quelques-uns :

 

La fin des guillemets magiques

Les magic quotes, déjà obsolètes depuis PHP 5.3, ont été supprimés en PHP 5.4.

Lorsque cette directive était activée, des antislashs étaient ajoutés aux guillemets (simples et doubles), et caractères NULL. A l’origine, le but était de protéger des injections SQL (on en avait déjà parlé dans un article plus ancien). Mais au final, le système était plus contraignant qu’avantageux car il fallait systématiquement faire l’usage de la fonction stripslashes (qui retire les antislashes) sur toutes les données envoyées par l’internaute, y compris celles qui n’avaient pas besoin d’être protégées.

Aujourd’hui, vous devez donc assurer vous-même la protection des données que vous envoient vos visiteurs en utilisant les requêtes préparées ou des fonctions comme mysqli_real_escape_string.

 

UTF-8 par défaut pour htmlentities et htmlspecialchars

Les fonctions htmlentities et htmlspecialchars prennent maintenant UTF-8 comme paramètre d’encodage principal (c’était ISO-8859-1 sur les versions 5.3 et précédentes).

Ainsi, si vous avez un site avec une base de données en ISO-8859-1 (latin1 pour MySQL) et que vous essayez de récupérer ces données via un simple « htmlentities($trucARecuperer) »… il est fort probable que rien ne s’affiche ! Si votre chaîne s’affiche correctement, c’est qu’elle ne contient pas de caractères spéciaux. Par contre, aux moindres é, è, à, ç rencontrés, ce sera assurément une chaine vide qui sera retournée !

Alors, comment régler le problème ? En utilisant les paramètres « optionnels » (entre guillemets car, maintenant, on ne peut plus vraiment dire qu’on ait le choix). La doc de php.net vous sera utile sur ce coup-là. Par exemple : htmlentities($trucARecuperer, ENT_QUOTES | ENT_IGNORE, ‘ISO-8859-1’) affichera la chaîne correctement. Rien de bien compliqué, n’est-ce pas ? Bon, par contre, si vous avez des centaines de fonctions à remplacer, vous risquez de trouver le temps long… Heureusement, il y a un « truc ».

Notez que sous PHP 5.6, la valeur d’encodage est définie par le paramètre default_charset du php.ini… Si vous êtes sur un hébergement mutualisé, il sera probablement configuré sur UTF-8 et vous n’aurez de toute façon pas la possibilité de le modifier, sauf en plaçant le code « ini_set(‘default_charset’, ISO-8859-1′) » en première ligne de vos fichiers. Cela pourrait vous être utile pour éviter d’avoir à modifier des centaines de pages.

 

L’extension MySQL originale désormais obsolète

J’en entends certains grincer des dents. Présente depuis la version 2.0 de PHP (autrement dit depuis novembre 1997 !), on aurait pu croire qu’elle resterait à vie au coeur de PHP, alors qu’elle n’était plus maintenue depuis déjà plusieurs années… Mais PHP 5.5 en a décidé autrement en plaçant l’API en deprecated. Finies donc les fonctions mysql_connect, mysql_query, mysql_fetch_array… Bien sûr, le processus prendra du temps avant leur suppression définitive de PHP (d’ailleurs, PHP 5.6 n’a toujours pas franchi le pas) mais on y viendra. PDO et MySQLi sont les alternatives.

– PDO peut être intéressant à utiliser si vous créez un nouveau site. Il est cependant orienté objet uniquement mais a l’avantage de pouvoir être (théoriquement) utilisé avec d’autres système de gestion de bases de données sans modifications de code (PostgreSQL par exemple).

– La seconde solution est donc MySQLi. MySQLi avec un i pour Improved. Elle permet la création de code orienté objet (ce que ne permettait pas l’ancienne API) ou en procédural. Si vous avez un site avec des fonctions mysql_, vous n’aurez alors qu’à les remplacer par mysqli_… Enfin, pas tout à fait car certaines fonctions mysqli_ ajoutent des paramètres ou en rendent certains obligatoires quand ce n’était pas le cas pour leurs « équivalents » mysql_. Mais cela ne présente aucune difficulté particulière. Une fois de plus, la doc de php.net vous sera utile pour pouvoir utiliser comme il le faut mysqli_connect, mysqli_query et les autres…

 

Les super globales ne peuvent plus être utilisées come noms de paramètres

Depuis PHP 5.4, ce code ne marchera donc plus : function foo($_GET, $_POST) {}. En fait, ce type de code était souvent utilisé en association avec des fonctions de type extract. Quelque chose comme extract($_POST) permettait ainsi de récupérer tous les noms de variables et leurs valeurs envoyés par l’internaute via un formulaire. Avec une boucle while et quelques lignes de codes, on pouvait ainsi créer de manière automatique les variables et assigner leurs valeurs.

Avec des risques de sécurité évidents. N’importe quel petit malin peut en effet trafiquer un formulaire HTML, et modifier ou ajouter les noms des champs. Et si l’un des noms de champs (qui devient donc une variable PHP via le script, on le rappelle) se mélange avec une variable déjà existante sur votre page (comme votre identifiant de connexion à la base de données), les risques peuvent être importants.

 

Bonnes mises à jour et bon courage. ;)

Les commentaires sont fermés pour cet article.