Aller au contenu | Aller au menu | Aller à la recherche

Site membre du réseau Izardev et LCNET

PHP Sécurité

Les failles de sécurité sur le web ne sont pas l'apanage de PHP comme le faire pressentir ce titre malheureux, vous pouvez tout aussi bien transposer cet article pour n'importe quel autre langage serveur tel ASP.NET ou JSP : voici un bref aperçu des principales failles et des pièges à éviter.

Il est important de considérer que l'on ne peut JAMAIS truster le contenu fourni par les internautes. N'allez pas croire que les formulaires en POST sont plus sécurisées que les formulaires en GET, ou inversement, il faut se méfier de toutes les sources extérieures ($_POST, $_GET, $_FILES etc.).

CSRF : Cross Site Request Forgery

Les attaques de type CSRF créent des requêtes HTTP vers un serveur tiers. Les hackers utilisent le navigateur de l'internaute pour effectuer des requêtes selon le souhait du hacker. J'en parle en premier car c'est celle qui semble la plus méconnue par le développeur standard, et pourtant elle peut faire des ravages.

Cela permet au hacker d'obtenir d'avoir accès à des crédits qu'il n'a pas en temps normal. Ces requêtes peuvent être exécutées via des frames, des requêtes AJAX, des <img> ou même des <object>.

Exemple

  • imaginons que la page www.monsite.com/admin/remove/node/1 permette de supprimer la page index de ce site dans son interface d'administration.
  • que j'ai une session ouverte du l'administration du site ligams (et peut donc accéder à cette fonctionnalité),

Un code de ce type serait une attaque CSRF :

<iframe border="0" width="1" height="2" src="http://www.monsite.com/admin/remove/node/1"></iframe>

Si mes formulaires d'administration ne sont pas protégés, un site tiers peut donc me faire exécuter les fonctionnalités d'administration du site ligams.com.
On peut tout imaginer par la suite : changement d'email, de mot de passe etc...

Mesures à prendre

  • Utiliser la technique des tokens (ou jeton de validité) dans chacun des formulaires,
  • Utiliser les variables $_POST plutôt que $_GET (quoi je me contredis ? mais c'est vraiment uniquement dans ce cas :) )
  • Vérifier l'entête HTTP REFERER (c'est rarement fait)
  • Demander à nouveau le mot de passe pour les opérations sensibles

XSS : Cross Site Scripting

La faille XSS consiste en la possibilité pour le hacker de pouvoir injecter du code dans les pages HTML. Il est donc possible si votre site a une faille XSS d'injecter du code HTML, CSS ou Javascript dans vos pages. L'insertion de code peut ainsi modifier la page et :

Rediriger l'utilisateur :

<script>document.location.href = 'http://www.ligams.com';</script>

Lire ses cookies :

<script>alert(document.cookie);</script>

Il est donc particulièrement important d'être vigilent, cette faille n'est pas anodine, notamment si vous utilisez les cookies.

Mesures à prendre

Les fonctions natives PHP à utiliser avant d'afficher du contenu sont :

  • htmlentities()
  • htmlspecialchars()
  • strip_tags()

Exemple de faille XSS

Il existe bien des manières d'ouvrir cette faille, la plus basique étant d'afficher une variable $_POST ou $_GET sans l'échapper :

<html>
<head></head>
<body><?php echo $_GET['valeur']; ?></body>
</html>

Le hacker n'a ici qu'à insérer son code dans l'URL en appelant cette page :

Il eût fallu faire :

<html>
 <head></head>
 <body><?php echo htmlentities($_GET['valeur']); ?></body>
 </html>

SQL Injection

Cette attaque, avec la précédente, sont sans doute les plus répandues sur internet. La technique d'SQLInjection est possible lorsque les requêtes d'une application WEB ne sont pas échappées correctement. Il est alors possible pour le hacker d'injecter du code SQL dans les requêtes.

le Hacker peut alors disposer de la base de données avec les mêmes droits que l'utilisateur utilisé pour se connecter à la base par le site attaqué.

Exemple de faille SQL

<?php
mysql_connect('localhost','MONUSER','MONPASS');
mysql_select_db('mabase');
$requete = mysql_query("SELECT * FROM users WHERE username='".$_GET['username']."' AND password='".$_GET['password']."'");
$user = mysql_fetch_array($requete);
?>
<html>
<head></head>
<body>Bienvenue <?php echo $user['username']; ?></body>
</html>

Appeler cette page de cette manière : page.php?username='; DROP TABLE users; --

Supprimera ainsi votre base de données users. Ce n'est pas restrictif, on peut obtenir de la base de données tout ce que l'utilisateur qui s'y connecte par le biais de la page (ici MONUSER).

Mesure à prendre

Echapper les requêtes des données non sûres (ou utiliser PDO et les requêtes paramétrées) :

$query = sprintf("SELECT * FROM users WHERE username='%s' AND password='%s'",
                    mysql_real_escape_string($_GET['username']),
                    mysql_real_escape_string($_GET['password']));
$requete = mysql_query($query);
$user = mysql_fetch_array($requete);

S'il s'agit d'un paramètre numérique, vous pouvez également le caster en int :

$query = sprintf("SELECT * FROM pages WHERE id='%d'",
                     (int) $_GET['id']);
 $requete = mysql_query($query);
 $page = mysql_fetch_array($requete);

Règles générales concernant PHP (configuration php.ini)

  • Ne pas afficher les erreurs :display_errors = Off
  • Loguer les erreurs : log_errors = On
  • Utiliser open_basedir dans les différents projets (pensez à /tmp pour l'upload de fichiers)
  • Utiliser disable_functions , par exemple : exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

Notez que la majorité des frameworks peuvent vous immuniser contre tous ces types d'attaque si vous en respectez les préconisations.

Articles connexes

Partagez cet article !

  • Delicious
  • Stumbleupon
  • Digg
  • Facebook
  • Google
  • Linkedin
  • Yahoo Buzz
  • Twitter
Vous avez apprécié cet article ?

Commentaires S'abonner au flux RSS des commentaires

  1. C'est bien de connaitre ces failles ainsi que les méthodes suivies pour assurer la protection. Si vous pouvez nous détailler chaque faille ainsi que sa solution dans un article dédié. C'est un sujet important et il est rare que je tombe sur un article que traite convenablement ce sujet.

Ajouter un commentaire

Les commentaires sont tous validés par un modérateur, votre commentaire n'apparaît pas directement sur le site.
Aucun support n'est assuré ici, vous pouvez néanmoins laisser vos remarques et critiques sur l'article, les points de vue pertinents sont toujours les bienvenus.