Mis à jour : 23 Déc 2020

Cet article ne remplace pas de bonnes connaissances en PHP, mais peut vous donner de réels bons conseils pour booster votre sécurité.
Il n’y aura ici rien à copier/coller directement dans vos fichiers PHP. Cependant, nous croyons que ces conseils et bonnes pratiques vous apporteront des bénéfices à long terme, en comprenant et en appliquant les différents points en fonction de vos besoins et de votre contexte.

Cet article est le troisième de notre série dédiée à la sécurité pour PHP.
Le premier article vous donne des indications pour la configuration de PHP, les mises à jour, le filtrage des données, ainsi que l’organisation du code.
Le second article traite de la protection contre les attaques les plus courantes.

Nous allons maintenant traiter des risques liés aux cookies, uploads, CRSF ainsi que de la sécurité par l’obscurité.

Protéger vos cookies

Ne stockez pas d’informations sensibles dans les cookies. Les cookies sont par nature non sécurisés, vous ne pouvez pas compter sur eux pour stocker (temporairement ou non) des données sensibles.
Pour protéger vos cookies contre les manipulations de données, une bonne solution est de les signer en calculant un hash (avec grain de sel), pour que le serveur puisse vérifier leurs contenus.
Ce hash doit être inclus dans les cookies eux-mêmes, et récupéré par le serveur.

Uploads de fichiers

Les envois de fichiers sont une fonctionnalité très sensible, car ils permettent à des utilisateurs d’envoyer des fichiers sur votre propre serveur. Une implémentation fragile permettra à des attaquants d’envoyer des fichiers PHP dans des répertoires exécutables, leur donnant la possibilité de faire à peu près tout sur le serveur.


Il n’existe pas de solution parfaite et simple. Il est donc nécessaire d’adopter une stratégie de défense en profondeur :

  1. Ne permettre l’envoi de fichiers qu’aux utilisateurs authentifiés
  2. Limiter la taille des fichiers envoyés
  3. Limiter les extensions et formats
  4. Créer un fichier .htaccess dans le répertoire parent des uploads de fichiers, spécifiant la liste des extensions autorisées. Exemple de directives, à adapter en fonction de votre contexte :
    deny from all
    <Files ~ “^w+.(gif|jpe?g|png|pdf)$”>
    order deny,allow
    allow from all
    </Files>
  5. Valider le type de fichier (valider avec une liste blanche les types de fichiers, et vérifier le type MIME)
  6. Lors de l’enregistrement des fichiers :
    1. Générer le nom des fichiers de manière aléatoire et ne pas se reposer sur des noms fournis par les utilisateurs
    2. Utiliser des noms uniques
    3. Vérifier que l’emplacement du fichier n’est pas déjà utilisé
    4. Sauvegarder les fichiers en dehors du dossier racine du site
    5. Après avoir enregistré les fichiers, retirer les permissions d’exécution sur le fichier (chmod)

La taille maximale des fichiers envoyés peut être configurée de manière globale dans le paramètre upload_max_filesize du php.ini. Si vous souhaitez définir une taille inférieure pour un formulaire en particulier, vous pouvez utiliser le paramètre MAX_FILE_SIZE du formulaire, mais effectuez une seconde vérification côté PHP, puisque ce paramètre peut être modifié par l’utilisateur lors de la soumission du fichier.

Vérifications complémentaires :
Si vous attendez une image de la part de l’utilisateur, vous pouvez par exemple vérifier la taille de cette dernière avec getimagesize. Si “false” est retourné, alors l’image n’est pas valide.
Pour aller un peu plus loin, le contenu du fichier peut être analysé, par exemple avec ClamAV.

Cross Site Request Forgery (CSRF)

Une première règle consiste à implémenter toutes les actions impliquant des changements d’état via des requêtes POST, au lieu de requêtes GET. Cela ne permettra pas en soi de supprimer le risque d’attaques CSRF, mais réduira le risque d’attaques basiques.
Pour vous protéger contre les attaques CSRF, l’utilisation de jetons anti-CSRF dans les formulaires est nécessaire. Ces tokens, stockés dans la session de l’utilisateur, seront comparés avec les valeurs retournées par les utilisateurs afin de valider/rejeter les actions.
Si vous n’utilisez pas de framework permettant l’implémentation directe de ce type de token, vous devrez alors les implémenter par vous-même, ou utiliser une librairie tierce. L’OWASP fournit un bon exemple d’implémentation, sur cette page.

La sécurité par l’obscurité

L’obscurité n’est pas un moyen d’empêcher les attaques, mais peut réellement ralentir les attaquants et cacher des informations précieuses qu’ils recherchent.

Vous pouvez par exemple cacher la version de PHP utilisée (des headers), en paramétrant expose_php à false dans le php.ini.

Un autre exemple est le formulaire de login : lorsque les utilisateurs fournissent des identifiants erronés, il n’est pas nécessaire de détailler la raison précise (par exemple : mauvais mot de passe). Se contenter de dire à l’utilisateur que les identifiants ne sont pas corrects est suffisant, et ne permettra pas à l’attaquant de connaître un login valide.

L’implémentation de sécurité est un processus continu et complexe. Tout d’abord, car celle-ci dépend de votre contexte particulier. Ensuite, parce que des nouveaux types d’attaques apparaissent au fil du temps.

Les différentes bonnes pratiques évoquées dans cette série d’articles permettent de se protéger contre des vulnérabilités techniques majeures, mais pas contre des failles logiques. En tant que designer fonctionnel et développeur web, vous devez également vous assurer que votre logique métier est sans faille et qu’elle ne peut pas être contournée ou abusée. Il n’y a pas de solution automatisée et générique contre cela, mis à part la revue de la logique de vos processus avec votre équipe.

Les frameworks de développement récents peuvent aussi vous aider à mettre en place des mesures de sécurité, ceux-ci incluant des solutions et patterns faciles à activer. Cependant, ces fonctionnalités de sécurité sont également faciles à désactiver, et toute erreur de configuration peut avoir un impact négatif. Il est donc important de prêter une attention toute particulière aux documentations détaillant l’utilisation de ces briques de sécurité. Les frameworks sont un bon moyen de bénéficier de l’expérience d’autres développeurs, et d’utiliser du code maintenu.