TUTORIELS 
PHP : se protéger contre les attaques XSS et CSRF
(Fourni par Direction|PHP)

Page 1 | 2 | 3

Tout ce qu'il faut savoir pour éviter de faire de son application PHP un danger potentiel pour son site.
 (octobre 2003)
 
Discutez en sur les forums
On connait souvent les attaques de type DOS (Denis de service), qui empêchent tout le monde d'accéder à un site. On connait aussi les failles des logiciels. On connait moins les tactiques utilisées pour obtenir des informations confidentielles d'un site ou d'y exécuter une actions sans avoir de droits. XSS consiste à injecter des données arbitraires dans les scripts, et les attaques CSRF consistent à faire exécuter des commandes involontaires aux utilisateurs accrédités d'un site. Voici comment s'en prémunir.

La sécurité est un sujet complexe. Les applications Web sont souvent décrites comme sécurisées ou non sécurisées. Cela conduit à des conceptions peu sécuritaires et beaucoup de confusion. Quel est le niveau de sécurité d'une application web sécurisée ? Par définition, les applications web "sécurisées" sont sécurisées à 100% et invulnérables à n'importe quel type d'attaque. Sur cette base, nous pouvons considérer chaque application web comme étant non sécurisée.

Maintenant que nous avons établi que toutes les applications web sont non sécurisées, je vais vous expliquer comment sécuriser davantage vos applications Web en détaillant 2 types d'attaques : Cross-Site Scripting (XSS) et Cross-Site Request Forgeries (CSRF). J'espère que vous n'apprendrez pas seulement des stratégies plus spécifiques de protection contre ces types d'attaques, mais, aussi et de manière plus importante, que vous allez acquérir une vue globale qui vous aidera plus généralement à comprendre la sécurité d'une application web.

Cross-Site Scripting
En tant que professionnel du PHP, vous avez probablement entendu parler de Cross-Site Scripting (XSS). En fait, vous avez déjà fait quelques actions pour protéger vos propres applications Web contre les attaques XSS. L'efficacité de telles mesures de prévention dépend de leur adaptation au problème ou seulement aux symptômes, et bien sûr de la manière dont vous comprenez le problème. La tendance générale est de se protéger spécifiquement d'une vulnérabilité, de la même manière que l'on résoudrait un bug en utilisant un cas de test spécifique. Avec cette stratégie, l'effort du développeur est moins efficace, et par conséquent, nous allons nous intéresser à la source du problème à chaque fois que c'est possible. L'erreur fondamentale qui conduit à des vulnérabilités de type XSS est de faire confiance aux données étrangères. Une recommandation générale parmi les développeurs est de ne jamais faire confiance aux données du visiteur. Mais se protéger contre les XSS nécessite encore plus de mé-fiance car n'importe quelle donnée étrangère peut être dangereuse. Qu'est-ce qu'une donnée étrangère exactement ? Tout simplement, une donnée étrangère est n'importe quoi que votre serveur web reçoit des visiteurs et qui vient de l'extérieur du site web. Des exemples de données étrangères incluent les messages postés sur un forum web, le courriel émis par un mail client web, une bannière publicitaire, les citations courantes fournies en XML via HTTP, et bien sûr les données du visiteur. Pour n'importe quelle application web intéressante, il y aura besoin de traiter des données étrangères et c'est le type d'application qui nécessite le plus d'attention. Bien sûr, le danger n'est pas spécifiquement lié au fait que vous fassiez confiance aux données étrangères, mais plutôt que vous supposez qu'elles sont valides et les renvoyez à vos utilisateurs sans validation particulière. Vos utilisateurs vous font confiance et les attaques XSS exploitent cette confiance.

Pour mieux comprendre pourquoi afficher des données étrangères peut être dangereux, considérez un système d'enregistrement simple où les utilisateurs fournissent leur nom d'utilisateur préféré et leur adresse courriel. Les informations enregistrées leur sont envoyées, une fois leur compte créé. Le formulaire HTML qui collecte cette information ressemblera probablement à celui-ci :

<form action="/register.php" method="post">
  <p>Username : <input type="text" name="reg_username" /></p>
  <p>Email: <input type="text" name="reg_email" /></p>
  <p><input type="submit" value="Register" /></p>
</form>

La figure 1 illustre la manière dont ce formulaire apparaît sur un navigateur web. Bien sûr, le script qui reçoit ces données est plus important que ce formulaire. Si les données qui ont été soumi-ses dans le formulaire ne sont pas proprement validées, des utilisateurs mal-intentionnés peuvent insérer un script dangereux, et votre seul espoir est que cet intrus ne soit pas très créatif dans ses attaques. Considérez que l'enregistrement des données est sauvegardé dans une base de données et que la formulation SQL utilisée pour sauvegarder ces données est la suivante :

if (!get_magic_quotes_gpc())
  {
  $_POST['reg_username'] = addslashes($_POST['reg_username']);
  $_POST['reg_email'] = addslashes($_POST['reg_email']);
  }
$sql = "insert into users (username, email) values ('$_POST['reg_username']', '$_POST['reg_email']}')";

Ce qui devrait vous inquiéter dans cette commande SQL est l'utilisation d'un tableau $_POST. Les appels à addslashes() sont seulement nécessaires pour s'assurer que la commande SQL n'est pas mutilée par les données elles-même (il est admis que la base de données utilisée évite les citations avec un anti-slash; modifiez cet exemple si nécessaire). Les données dans $_POST viennent du client, et ce code affiche une confiance aveugle en ces données. Avec des utilisateurs légitimes, les dangers de cette approche restent cachés, et c'est exactement de cette manière que de nombreuses vulnérabilités d'applications web sont nées. Considérez le nom utilisateur suivant :

<script>alert('Oh Non!');</script>

Alors que nous pouvons facilement déterminer que ce n'est pas un nom d'utilisateur valide, cela démontre comment le code que nous écrivons n'est pas si prudent. Sans une validation propre des données sauvegardées, n'importe quoi peut se passer dans la base de données. Bien sûr, le danger dans le cas de XSS réside dans l'effet produit lorsque ces données sont renvoyées aux autres utilisateurs.

Admettons que ce système d'enregistrement ait une application administrative correspondante qui soit seulement accessible à partir du réseau local par les administrateurs autorisés. Il est facile de supposer qu'une application inaccessible depuis Internet est sûre, et que moins d'efforts doivent être fournis pour la sécurité d'une telle application. Considérez le code du listing 1 qui donne une liste d'uitlisateurs enregistrés aux administrateurs autorisés.

<table>
  <tr>
    <th>Usager</th>
    <th>Email</th>
  </tr>
<?
  if ($_SESSION['admin_ind'])
    {
    $sql = 'select username, email from users';
    $result = mysql_query($sql);
    while ($curr_user = mysql_fetch_assoc($result))
      {
      echo "\t<tr>\n";
      echo "\t\t<td>{$curr_user['username']}</td>\n";
      echo "\t\t<td>{$curr_user['email']}</td>\n";
      echo "\t</tr>\n";
      }
    }
?>
</table>

Si les données dans la base de données ne sont pas validées avant d'être sauvegardées, un administrateur peut être sujet à une attaque XSS en utilisant cette application. Ce risque est illustré dans la figure 2.Ce risque est même encore plus évident si vous considérez un script bien plus vicieux du côté du client comme présenté sur le listing 2.

<?
  $token = md5(time());
  $_SESSION['token'] = $token;
  $_SESSION['token_timestamp'] = time();
?>
<form action="/developpeur/add_post.php" method="post">
  <input type="hidden" name="token" value="<? echo $token; ?>" />
  <p>Subject: <input type="text" name="post_subject" /></p>
  <p>Message: <textarea name="post_message"></textarea></p>
  <p><input type="submit" value="Add Post" /></p>
</form>

Si ce script est affiché par un administrateur, les cookies de l'administrateur qui sont associés avec le domaine de l'application courante sont envoyés à mechant.exemple.org pour une collecte possible. Dans cet exemple, le script distant vole_cookies.php peut accéder à ces cookies via la variable $_GET['cookies']. Une fois capturés, ces cookies peuvent être utilisés pour lancer des attaques d'usurpation d'identité, obtenir des données sensibles, et ainsi de suite.

Page 1 | 2 | 3

 

 
[ Chris ShiflettDirection|PHP pour JDNet
 
Accueil | Haut de page