June 2010 Archives

16-06-2010 22:23:48

[Secu]Ne jamais stocker son pass MySQL en clair

J'ai constaté que tous les scripts PHP utilisant MySQL stockaient le mot de passe MySQL en clair dans le code. Le risque est donc qu'en exploitant une LFI ou si un pirate arrive à avoir un shell sur le serveur, il lui suffira de lire les script php pour obtenir le pass MySQL et se connecter à cette base via un phpmyadmin par exemple.

J'ai donc essayer de trouver les différentes méthodes pour ne pas donner son mot de passe MySQL en clair.

La première solution consiste à utiliser le mod_env et les variables d'environnement d'Apache. Il suffit d'ajouter dans le fichier de config du VirtualHost de son site la variable comme ceci :
SetEnv passmysql "voicilepass"
Pour se connecter à MySQL, il suffira alors de mettre dans son code PHP la ligne suivante :
$con = mysql_connect($host, $login, $_SERVER['passmysql']);
Le pass ne sera donc plus dans le code ce qui est un peu mieux. L'inconvénient est que le pass est toujours visualisable si le pirate fouille un peu et va voir dans la conf d'Apache. De plus le pass apparaitra dans le phpinfo() car cette fonction récapitule les variables d'environnement Apache.

J'ai donc pensé à une 2e méthode.

L'objectif est de partager une variable accessible par tous les processus utilisant PHP. Pour cela il existe les sémaphores !

Nous allons donc commencer par créer un script launch.php initialisant la sémaphore et ajoutant la variable $pass_mysql dans la mémoire partagée :
<?php
$pass_mysql = "mot_de_passe";

$shm_id = shm_attach(1);
if ($shm_id === false)
{
    echo "Fail to attach shared memory.\n";
}
//On ajoute $pass_mysql dans la memoire partagee
if (!shm_put_var($shm_id, $pass_mysql, $pass_mysql))
{
    echo "Failed to put var 1 in shared memory $shm_id.\n";
}
?>
Maintenant que le mot de passe est partagé, nous pouvons supprimer le fichier :
# rm launch.php
Créons ensuite le fichier de connexion à MySQL qui utilisera alors la variable stockée dans la mémoire partagée :
<?php
$shm_id = shm_attach(1);
if ($shm_id === false)
{
    echo "Fail to attach shared memory.\n";
}
//Recuperation du pass mysql dans la memoire partagee
$pass = shm_get_var($shm_id, $pass_mysql); 

$con = mysql_connect('localhost', 'root', $pass);
mysql_select_db('test');

$req = "select * from `table` where id=1";
$res = mysql_query($req);
$ligne = mysql_fetch_array($res);
echo $ligne['nom'];
?>
Et voila nous avons une configuration opérationnelle et qui permet de ne pas stocker dans un fichier en clair le pass de sa base de donnée MySQL.

Le seul inconvénient est qu'il faudra réuploader le fichier launch.php à chaque redémarrage de la machine et relancer celui ci en pensant à bien le supprimer ensuite.

Posted by cloud | Permanent link | File under: Security, Coding