Le problème a une origine toute bête : ma fainéantise... En effet, Les Visiteurs a été développée à une époque où les problèmes de sécurité n'étaient pas encore aussi critiques qu'aujourd'hui, et où register_globals était à on par défaut dans PHP. Tous les développeurs PHP connaissent la dangerosité de ce paramètre, et c'est pourquoi il est de nos jours très fortement recommandé de le mettre à off, comme c'est le cas par défaut dans les versions actuelles de PHP.

Mais comme Les Visiteurs avait été développé à l'ancienne, l'application ne fonctionnait pas avec register_globals à off. Pour palier rapidement au problème sans revoir tout le code existant, je me suis contenté de mettre un extract($_GET) au début du fichier config.inc.php. Erreur fatale, cette petite ligne rend le code aussi peu sécurisé que lorsque register_globals est à on : en passant un lvc_include_dir dans l'URL, on peut utiliser certains scripts de l'application pour exécuter du code malicieux et compromettre la sécurité du serveur en escaladant petit à petit les droits (en profitant de certains failles de PHP et du noyau Linux, un accès root est possible...).

Je n'ai pas vraiment le temps de publier une nouvelle version en ce moment, mais voici ce qu'il faut modifier dans include/config.inc.php pour corriger la faille :

extract($_GET);

à remplacer par :

extract($_GET);
if (isset($_GET["lvc_include_dir"])) {
  exit;
}

Ainsi, l'exécution de tous les scripts de l'application (ils font tous appel au fichier de config) sera interrompue si un attaquant tente de forcer la valeur de lvc_include_dir via l'URL. Ce correctif peut aussi s'appliquer à la version 2, mais il faudra alors l'appliquer à tous les fichiers utilisant la variable $lvc_include_dir : admin/admin.php3, include/config.inc.php3, include/library.inc.php, include/menus.inc.php, include/new-visitor.inc.php3, include/update-agents.php, include/update-isp.php, image-vis.php3 et index.php.

Il s'agit bien entendu d'un correctif temporaire, en attendant que Les Visiteurs 3.0 soit finalisée, avec une réécriture du code pour pouvoir se passer du extract et remplacer la variable $lvc_include_dir par une constante, pour empêcher toute injection d'une nouvelle valeur.

Je profite également de ce billet pour vous suggérer très fortement de bloquer directement les include sur des fichiers distants, d'autant plus que ce n'est pas extrêmement compliqué à faire :

  • sous PHP 5.2 et supérieurs, il suffit de positionner le paramètre allow_url_include à off dans php.ini,
  • dans les versions antérieures de PHP, il faut positionner allow_url_fopen à off dans php.ini (attention, contrairement au nouveau paramètre allow_url_include, allow_url_fopen s'applique à toute opération sur un fichier distant, même une simple lecture).

Vous pouvez aussi empêcher ces opérations avec l'extension Suhosin, qui bloquera également bon nombre d'autres vecteurs d'attaques.