Sécurité PHP MYSQL
Le but de cet article est de vous présenter quelques notions en matière de sécurité PHP / MySQL. Les pirates insèrent souvent du code dans une page HTML ou PHP, par injection de code, généralement par :
- le biais d'un formulaire HTML qui permet d'entrer des données dans la base de données
- ou alors en insérant des données par le biais de la barre d'adresse de la fenêtre,
- par l'upload d'un fichier
- ou toute autre voie d'accès au serveur possible.
L'article est ici succint, mais pour aller plus loin dans les connaissances il s'agit de se référer à ce guide de sécurité PHP en ligne : http://phpsec.org/.
SECURITE SQL
Les bases de données permettent d'assurer le stockage des informations en liaison par exemple avec des pages HTML couplées avec PHP. Donc tout le monde peut en avoir accès par l'intermédiaire d'un client relié au seveur. MySQL basé sur SQL est notamment très utilisé avec PHP. Il est donc pertinent d'examiner quelques notions de sécurité en matière de SQL.
En ce qui concerne SQL, il faut savoir premièrement qu'une astuce de programmation ou un détournement de requête possible à partir d'un serveur a de bonnes chances de réussir sur un autre serveur et il en est de même avec les applications, qui peuvent être utilisées afin d'atteindre le serveur et d'en saccager les données.
Les risques dans les manipulations de données
On en retrouve plusieurs types :
- Coutournement d'une clause where, c'est-à-dire neutraliser la clause WHERE en injectant une condition constante (toujours vraie ou toujours fausse, comme par exemple : SELECT * FORM table WHERE 1;
- Modification sans limite, comme par exemple la destruction totale de données avec la commande DELETE : ex. l'injection de DELETE FROM table WHERE 1;
- Insertions indésirables, où le pirate peut injecter une ligne complète qui sera traitée par la base de données à son insu. Des valeurs sont ainsi insérées dans l'application, qui n'en est plus maîtresse, par exemple le pirate peut injecter : md5('secret') dans un formulaire, ce qui revient à crypter le mot 'secret', que la base de données ne pourra plus retrouver ou traiter.
- Exécutions multiples : par exemple une injection pour placer une requête dans une autre requête initiale, afin d'exécuter toutes les injections que veut le pirate.
- Surcharger le serveur : c'est-à-dire modifier une requête afin qu'elle engendre une charge de travail importante et inutile pour le serveur.
- Exportations cachées : en exportant des données, en les extrayant de leur dépôt habituel et les placer par la suite dans un réceptacle public plus facile à lire. Cela ce fait par exemple en coutournant la clause WHERE, ou alors en insérant des fichier externes directement sur le serveur SQL.
Chiffrement d'un password
Le cryptage d'un password ou d'une données consiste par sa transformation en une autre données par le biais d'une méthode extrêmement dure ou impossible à découvrir. MySQL offre des méthodes de chiffrement des données et par la même du mot de passe. Nous avons par exemple :
INSERT INTO utilisateurs(identifiant, motdepasse) VALUES ('$id', MD5('$mdp'));
Vérification :
SELECT id FROM utilisateurs WHERE identifiant = '$idTest' AND motdepasse = MD5('$mdpTest');
Pour du contenu sécurisé à afficher :
Stockage :
INSERT INTO dossiersSecrets(titre, contenu) VALUES ('$titre', AES_ENCRYPT('$contenu','motdepasse'));
Récupération :
SELECT titre, AES_DECRYPT(contenu,'motdepasse') AS contenu FROM dossiersSecrets;
Dans le premier exemple la fonction MD5 permet de chiffrer les données, de sorte qu'elles ne puissent être déchiffrées par la suite. Ici on peut juste vérifier en fait que le password encrypté par le développeur et inséré dans la base de données corresponde bien au password entré par l'utilisateur à travers le système de login, ensuite crypté par l'application selon la même méthode, ici en l'occurence md5.
Tandis que la deuxième fonctionnalité 'AES_ENCRYPT' permet de crypter une données que l'on peut ensuite décrypter par la fonctionnalité 'AES_DECRYPT'.
SECURITE PHP
L'injection de code par des voies détournées est toujours ici de mise. Voici quelques types d'attaques que l'on retrouve fréquemment :
- l'injection de code distant.
Par exemple, c'est introduire une instruction PHP dans une page, qui ira chercher du code PHP sur un site distant pour le ramener sur le serveur local du pirate et l'exécuter comme code local, afin de prendre contrôle du serveur et des données du serveur distant piraté.
- l'exécution du code à la volée.
Cela ce fait par exemple à l'aide de : eval(), fonction qui prend en argument une chaîne de caractère pour l'exécuter comme du code PHP; et par là même exécuter des opérations destructrices de données par cette voie.
- le téléchargement de fichiers; ce qui permet d'importer du code PHP sur un site.
Il suffit en effet que ce site ait des autorisations de lecture et qu'il soit accessible depuis le Web, sans besoin de droit d'exécution ou d'écriture pour exécuter tous les codes PHP que veut le pirate. En stockant le fichier, par la fonction "upload" (ex. image), le code est exécuté sur le serveur piraté et vient en saboter ou déranger le fonctionnement.
- La directive register_globals;
si elle est activée permet d'injecter dans les scripts toutes sortes de variables; ce qui rend la programmation de script peu sûr. Heureusement que dans les versions supérieures à PHP 4.2 l'option register_globals est désactivée.
- filtrage des données;
c'est-à-dire la gestion des erreurs, ou les mécanismes par lesquels l'application web déterminera la validité des données qui entrent et sortent de l'application, par exemple au travers d'un formulaire. Il s'agit donc de s'assurer que : permièrement on ne puisse pas contourner le filtrage des données, que deuxièmement les données invalides ne puissent pas être confondues avec des données valides et enfin identifier l'origine des données.
Vous trouverez les solutions possibles à ces problèmes dans ce guide de sécurité PHP en ligne : http://phpsec.org/.
Chiffrement en PHP
Tout comme MySQL, PHP permet également de chiffrer des données. Voici un exemple avec la fonction md5 qui est une des fonctionnalités la plus sûre :
Exemple avec Md5 :
<?php
// le nom, le mot de passe et son login
// sont stockés dans $nom, $pass et $clef.
if ($HTTP_POST_VARS)
{
$password = md5($pass);
$login = md5($clef1);
echo "Mot de passe: ".$pass."<br>";
echo "Son <i>code crypté</i> est: ".$password."<br>";
echo "Votre login : ".$clef1;
// $nom, $password et $clef1 sont ensuite stockées
// dans la base de données.
}
?>
UTILISER LES EXPRESSIONS RÉGULIÈRE POUR FILTRER LES INPUT (ex. formulaire, password)
Une autre mesure que l'on peut prendre pour sécuriser les données et de filtrer les input selon des conditions : surtout entrées de formulaire et password. Ainsi, si par exemple, une interface informe l'utilisateur que son password n'est pas assez sur car pas alphanumérique, cela le poussera à faire des efforts et entrer un code, moins banal, donc plus difficile à découvrir.
Les Expressions régulières (regex ou regexp) permettent de manipuler et de contrôler justement le contenu d’une chaîne de caractères; et donc filtrer des input, dont les password.Pour vérifier qu’une variable ou un input (champs de formulaire par exemple) corresponde bien au type de données demandés il s’agit de comparer la chaîne concerne au code regex prédéterminé.
Quel est le lien avec la sécurité ?
Cette méthode permet par exemple de filtrer les données qui sont entrées dans formulaire ou peut obliger l’utilisateur à utiliser un certain type de password, plus solide dans sa composition (par exemple n’entrer que des passorwd alphanumériques).
En terme de programmation PHP, cela se traduit comme ceci :
$chaine = ‘bonjour le monde'; if( preg_match( '/bonjour/', $chaine ) ) echo 'Trouvé'; else echo 'Non trouvé';
Ce script permet de vérifier que $chaîne répond aux conditions de filtrage. Ici en occurence, la chaîne doit comporter le terme "bonjour". Au sujet de la sécurité, on peut très imaginer qu’avec cette méthode l’ordinateur refuse et communique au sujet, qu’il ne pas entré un password de type alphanumérique. C’est d’ailleurs un cas de figure qui se rencontre banalement. Il suffit d’utiliser cette expression régulière dans le script suivant :
<?php
$chaine='abcd123EFGH';
if(ereg("^[[:alnum:]]+$", $chaine))
{
echo 'La chaîne est alphanumérique';
} else {
echo 'La chaîne n\'est pas alphanumérique';
}
//Ou on peut utiliser la REGEX suivante:
ereg("^[0-9A-Za-z]+$", $chaine);
?>
Ici la variable chaîne est comparé à : ^alnum:+$ qui signifie bien ce à quoi il est destiné, mais aussi à : ("^[0-9A-Za-z]+$ qui est une autre façon moins économique de comparer $chaine aux conditions d’input alphanumériques.
LA SOLUTION DES SYSTEMES DE GESTION DE CONTENU OU DE CREATION DE SITE WEB
Une autre solution est d'utiliser des systèmes de création et de gestion de contenu Web, pour créer un petit site web perso et l'agrémenter d'une petite bases de données. L'avantage ici est que si vous utilisez par exemple une application comme http://sites.google.com/; la sécurité est ici gérée par de grandes sociétés comme 'Google', qui engage des experts en la matière. Il devient dès lors très difficile pour des pirates de saccager les données de l'application web que vous créez, ainsi que la base de données, car beaucoup d'options de piratage sont envisagées et contrecarrée par des professionnels de la sécurité travaillant pour ces sociétés.
Sites.google, par exemple, est une application en ligne qui permet le plus simplement possible de créer un petit site Internet perso agrémenté d'une base données. Pas besoin ici de sécuriser les données c'est la société Google, qui s'en charge ! Par exemple, Google.site permet de rassembler rapidement en un seul endroit une série d'informations, tout en sécurité :
- vidéos
- agendas,
- présentations,
- informations stockées dans une base de données,
- pièces jointes,
- texte.
Elle permet également en matière de sécurité d'autoriser leur accès ou leur modification à un groupe restreint, ou carrément au monde entier. Encore une fois, il y a ici la garantie de Google en matière de sécurité des informations.
Voici cependant quelques mesures de sécurité qui sont offertes à l'utilisateur :
- supprimer quelqu'un d'un site;
- contrôler l'accès au site;
- supprimer des commentaires et des pièces jointes;
- système de login avec password.
En matière de password il est à noter qu'il s'agit d'avoir sous la main trois types de password selon leur utilité : un pour des applications banales sans importance que vous utilisez, l'autre pour des applications personnelles (ex. e-mail), et l'autre enfin plus complexe pour des informations hautement importantes et confidentielles que vous désirez gérer depuis Internet (ex. password pour une application de e-banking).
REFERENCE
PHP Security Consortium : http://phpsec.org/.