Outils pour utilisateurs

Outils du site


langages:php:astuces

Ceci est une ancienne révision du document !


Flottants vs locales

PHP sait formater un flottant en fonction de la locale (catégorie LC_NUMERIC) :

setlocale(LC_NUMERIC, NULL);
echo 3.14;

Affichera 3,14 (pour une locale française)

Par contre, gare à l'ensemble des casts, même implicites, de float vers string (penser au SQL) car le point de la partie décimale sera modifié. Plus grave, de cette particularité :

L'information locale est maintenue par processus, non par thread. Si vous faites fonctionner PHP sur un serveur multi-threadé comme IIS ou Apache sur Windows, vous pourriez obtenir des changements soudains des configurations locales pendant qu'un script fonctionne, même si celui-ci n'appelle jamais la fonction setlocale(). Ceci survient à cause des autres scripts qui fonctionnent dans des threads différents du même processus. Ces scripts changent les configurations locales dans le processus au complet en utilisant la fonction setlocale().

Connaître sa locale (sans la modifier)

La documentation est imprécise, une valeur NULL comme '' (chaîne vide) sous Windows la modifie pour celle du système. La valeur correcte est bien '0' :

var_dump(setlocale(LC_NUMERIC, '0'));

PDO/MySQL : limiter la casse en cas d'injection

Si vous n'exploitez pas la possibilité de pouvoir exécuter plusieurs requêtes en même temps, j'entends :

$bdd->query('SELECT * FROM foo; SELECT * FROM bar');

Alors vous devriez sérieusement envisager de compiler l'extension pdo_mysql sans cette option en modifiant le code source de ext/pdo_mysql/mysql_driver.c en commentant ces lignes :

#ifdef CLIENT_MULTI_STATEMENTS
        |CLIENT_MULTI_STATEMENTS
#endif

Parce que le jour où vous avez une injection de ce type :

$bdd->query('SELECT * FROM users WHERE id = ' . $_GET['id']);

Si l'attaquant entre, par exemple, dans l'URL (je l'écris en non urlencodé par facilité) :

?id=1;DROP TABLE users

Les effets d'une injection comme celles-ci seront particulièrement dévastateurs. Par défaut, avec l'ancienne extension mysql, ce genre d'injection n'est pas possible car cette option est désactivée.

A partir de PHP 5.6.5, il sera possible de désactiver cette option en PHP sans avoir à patcher et recompiler PHP. Pour ce faire, il sera nécessaire d'ajouter l'option `PDO::MYSQL_ATTR_MULTI_STATEMENTS ⇒ FALSE` en 4e paramètre du constructeur PDO (le tableau options). Notez que vous ne pouvez pas passer par PDO::setAttribute, il serait trop tard donc purement et simplement ignorée, car cette option doit être désactivée au moment d'établir la connexion et pas après.

langages/php/astuces.1420909322.txt.gz · Dernière modification: 10/01/2015 18:02 de julp