II. Astuces 1 à 9▲
#1 : Tenez votre version de PHP à jour▲
Vous recherchez l'astuce ultime ? J'ai de mauvaises nouvelles pour vous, elle n'existe pas. La sécurité est à la fois un effort constant et de nombreuses petites choses, plutôt qu'une seule astuce toute puissante. Cette semaine nous lançons une nouvelle section sur la DevZone : « L'astuce sécurité de la semaine ». Pour faire correctement les choses, nous allons en publier une par jour durant le mois de mars. Quelques-unes de ces astuces seront des actions spécifiques que vous pourrez entreprendre, certaines seront des concepts généraux dont il faut avoir conscience, toutes seront brèves. Sans plus de préambule, voici la première astuce.
Tenez à jour votre version de PHP.
De même qu'avec n'importe quel autre langage, des vulnérabilités seront découvertes. Utiliser la version la plus récente et se tenir au courant des améliorations vous aidera à conserver des applications sécurisées, efficaces et stables.
La version actuelle de PHP peut toujours être trouvée ici.
Si vous souhaitez partager une astuce sécurité, enregistrez-vous sur la DevZone et sélectionnez le lien Contribute dans le coin supérieur droit. Nous sommes une communauté, faisons de la sécurité un effort communautaire.
#2 : N'affichez pas les erreurs en production▲
La sécurité par obfuscation n'est pas de la sécurité le moins du monde. D'un autre côté, il n'est pas non plus souhaitable de donner des informations sur votre site. L'astuce qui suit est simple, mais elle est fréquemment ignorée en environnement de production.
Assurez-vous de ne pas afficher les erreurs et ainsi de potentiellement divulguer des informations sur votre site.
En mettant display_errors à OFF dans le php.ini de votre serveur de production, vous empêchez la divulgation d'informations qui pourraient donner aux attaquants des indices quant à la structure de votre système. Par défaut, display_errors est à ON.
Vous trouverez davantage d'informations et de possibilités de rapport d'erreur dans la section « Introduction à la Gestion des erreurs et aux fonctions de log » du manuel.
#3 : Auditez votre code▲
Être conscient de la sécurité est une bonne chose, mais cela ne résout pas tout le problème. Les développeurs doivent être vigilants lorsqu'il s'agit de sécurité. Et même ainsi, vous ne pouvez pas le faire seul. L'astuce d'aujourd'hui vous le rappelle.
Puisque votre application pourrait contenir des failles de sécurité auxquelles vous avez été exposé, des services et applications tiers devraient être pris en considération afin d'aider à faire intervenir une nouvelle perspective et à trouver les faiblesses qui n'ont pas encore été identifiées.
En tant que développeur, vous devriez avoir dans votre trousse à outils des éléments vous aidant à trouver les faiblesses de sécurité dans vos applications. Des outils comme Chorizo vous aideront à analyser automatiquement votre code. Des programmes comme PHPSecInfo vous assureront d'avoir un environnement configuré convenablement.
Utiliser de tels outils et des scanneurs ne devrait pas être les seules mesures prises pour améliorer la sécurité. Cependant, elles ont une part importante dans l'ensemble. Laissez à des projets et à des éditeurs de confiance le soin de vous aider à construire des applications sécurisées.
#4 : Évitez les noms par défaut▲
Le proverbe dit : « La sécurité par obfuscation n'est pas de la sécurité ». Cependant, le revers de la médaille est que l'obfuscation, lorsqu'utilisée comme partie d'une stratégie d'ensemble, est une bonne chose. Il n'y a aucun intérêt à rendre la vie facile à ceux qui ont des intentions malicieuses. Cela nous ramène à notre astuce du jour.
Évitez les noms par défaut pour les fichiers et les répertoires contenant des informations primordiales.
Ne vous comptez pas sur des noms obscurs pour améliorer la sécurité de votre application. Vous devriez toujours vérifier les droits d'accès, tester les vulnérabilités avec des outils et garder un œil sur les fichiers log pour veiller aux activités suspicieuses. Cela dit, au moment de construire le design de vos applications et de vos sites Web, ne facilitez pas la tâche des mauvaises personnes pour ayant de mauvaises intentions. N'utilisez pas des noms par défaut ou trop communs pour vos fichiers et répertoires.
#5 : Ne faites jamais confiance à l'utilisateur▲
La sécurité en PHP est une mission continue qui demande au programmeur de penser aux paramètres externes à l'application. Il n'est plus suffisant, de nos jours, de simplement penser « Cela fait-il ce que je veux ? » ; vous devez également prendre en compte « De quelle autre manière les gens peuvent-ils l'utiliser, est-ce que je souhaite les y autoriser ? ». L'astuce d'aujourd'hui est un proverbe que tous les programmeurs devraient réciter quotidiennement :
Ne jamais faire confiance à l'utilisateur.
C'est un triste fait dans la vie, mais les utilisateurs sont vils. Ils ne cherchent rien de mieux que de trouver un moyen d'exploiter votre application. Dès que vous laissez tomber votre garde et que vous commencez à penser « je vends seulement de petites peluches, mes utilisateurs sont-ils vraiment méchants ? », vous avez perdu la bataille.
OK, ce n'est peut-être pas aussi dramatique, mais vous devez garder un œil vigilant sur vos visiteurs. C'est ici qu'intervient le second proverbe à réciter quotidiennement par tous les développeurs :
Filtrer la source (input), protéger la sortie (output). (Filter Input, Escape Output)
Oui, FIEO (OK, cela n'a pas aussi bonne allure que GIGO) est l'un des mantras que tous les programmeurs qui pensent à la sécurité doivent adopter.
#6 : Pour utiliser des nombres dans du SQL, castez systématiquement▲
Le thème de l'écriture d'applications PHP sécurisées couvre davantage que simplement écrire du bon code PHP. La plupart des applications utilisent une base de données, quel qu'en soit le type. Bien souvent, des vulnérabilités affectant toute l'application sont introduites en construisant du code SQL. L'astuce du jour traite d'une solution simple que les développeurs peuvent implémenter.
Toujours caster les valeurs numériques en les envoyant dans les requêtes SQL.
Même si vous filtrez l'input, une bonne méthode de sécurité (et simple à mettre en place) est de caster les valeurs numériques dans la requête SQL. Prenez par exemple le code suivant :
$myId
=
filter_var($_GET
[
'
id
'
],
FILTER_VALIDATE_INT);
$sql
=
'
SELECT * FROM table WHERE id =
'
.
$myId
;
Même si vous appliquez le filtre natif de PHP 5.2, vous pouvez ajouter un niveau de protection. Essayez plutôt ceci :
$myId
=
filter_var($_GET
[
'
id
'
],
FILTER_VALIDATE_INT);
$sql
=
'
SELECT * FROM table WHERE id =
'
.(int)
$myId
;
Ce cast final en valeur entière enlève tous les doutes quant à ce qui est envoyé à MySQL. L'exemple ci-dessus est volontairement simplifié. En situation réelle, le code serait plus complexe et le risque d'erreur serait bien plus grand. En appliquant le dernier cast lors de la construction de la requête, vous introduisez un niveau supplémentaire de sécurité.
#7 : Nettoyez les sessions▲
L'astuce d'aujourd'hui vient de Kevin Schröder et des jeunes (mais néanmoins doués) esprits des Services Professionnels Zend.
Lorsque vous utilisez session_regenerate_id() pour protéger contre l'attaque « session fixation », il est généralement une bonne idée de supprimer l'ancien ID de session.
Par exemple, le script :
<?php
session_start();
$_SESSION
[
'data'
]
=
time();
session_regenerate_id();
?>
Allez une première fois à l'URL et consultez le répertoire /tmp :
sess_82c6980017e100277a63983142fd454c
sess_a4bab88e6dfa6e900ade21e3fbd27a53
Allez-y une seconde fois, vous verrez :
sess_984c5230acca90b5a75eddb89bb48354
sess_a4bab88e6dfa6e900ade21e3fbd27a53
sess_82c6980017e100277a63983142fd454c
Allez-y une nouvelle fois, vous verrez :
sess_984c5230acca90b5a75eddb89bb48354
sess_a4bab88e6dfa6e900ade21e3fbd27a53
sess_82c6980017e100277a63983142fd454c
sess_dd88c05b724d80b30c90309847f2e919
Ces sessions sont encore actives. Pour les supprimer en régénérant l'ID, utilisez le code suivant :
<?php
session_start();
$_SESSION
[
'data'
]
=
time();
session_regenerate_id(true
);
?>
Si vous utilisez votre propre gestionnaire de session, cela aura pour effet d'appeler votre fonction « destroy » de callback.
Bien que cela ne fasse ou ne détruise pas une application sécurisée, cela vous apporte un niveau supplémentaire de sécurité contre la fixation de session et cela vous coûte seulement quatre caractères de code.
#8 : Validez systématiquement l'input utilisateur▲
Dans les sujets de sécurité PHP, il y a toujours plus d'une manière d'accomplir une tâche. Souvent, c'est en combinant des tactiques que l'on obtient la meilleure sécurité. Nous avons déjà parlé de filtrer les données, mais, au-delà de filtrer, nous devons rester vigilants et valider les données provenant de l'utilisateur. Cela nous amène à notre astuce du jour.
Toujours valider l'input utilisateur.
Prenez par exemple le code suivant :
<?php
$myFile
=
filter_var($_GET
[
'file'
],
FILTER_SANITIZE_STRING);
include($myFile
);
?>
Appeler http://example.com/file.php?file=home.php obligera votre script à inclure le script home.php dans le répertoire courant. Toutefois, si quelqu'un venait à demander l'adresse http://example.com/file.php?file=badcode.php, vous vous exposez potentiellement à exécuter son code ou bien votre code que vous ne souhaitez pas exécuter dans ce contexte.
Ne dépendez pas uniquement de file_exists(). Simplement parce que c'est un fichier local ne signifie ni que le fichier est valide, ni qu'il est à vous. Ne facilitez pas la tâche aux pirates pour exécuter leur code sur votre serveur.
Pour protéger de cela, toujours filtrer et valider :
#9 : Conservez les informations et le code sensibles à l'extérieur de votre arborescence Web▲
Ce sont parfois les idées les plus simples qui sont les plus importantes. Cette idée semble simple, mais je suis toujours surpris par la faible quantité de personnes qui la comprennent et qui l'implémentent.
Conservez les informations et le code sensibles à l'extérieur de votre arborescence Web
Considérez la structure suivante :
/htdocs
/includes
/images
/js
Si vous conservez vos informations de connexion à la base de données dans un fichier db.inc et que vous le placez dans le répertoire includes, il est possible pour quelqu'un de télécharger vos informations en allant à l'adresse http://example.com/includes/db.inc. Puisque la plupart des serveurs ne donnent pas d'informations spécifiques sur la manière de gérer les fichiers .inc, ils sont traités comme du texte s'ils sont demandés directement. Les implications sont évidentes. Si vous conservez les informations de connexion dans un fichier portant une extension autre que « .php » et à l'intérieur de la racine de votre serveur Web, il y a de grandes chances pour que vous laissiez filer des informations.
La solution est simple. Placez toutes vos informations sensibles à l'extérieur de la racine du serveur Web. De nombreux experts argumentent qu'il est mieux de placer la majorité, si ce n'est l'ensemble, du code PHP à l'extérieur de la racine de votre serveur Web. Puisque PHP n'est pas limité par les mêmes restrictions que votre serveur Web, vous pouvez faire un répertoire au même niveau que votre serveur Web et y placer toutes vos informations et votre code sensibles.
/phpinc
/includes
/htdocs
/images
/js