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 a ici rien à copier/coller directement dans vos fichiers PHP. Cependant, il est possible d’en tirer 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 deuxième de notre série dédiée à la sécurité pour PHP. Le premier article “Protéger votre site : Bonnes pratiques de sécurité pour PHP #1” vous donne des indications pour la configuration de PHP, les mises à jour, le filtrage des données, ainsi que l’organisation du code.

Nous allons à présent examiner comment se défendre contre les attaques les plus courantes.

Vous défendre contre les attaques les plus courantes

Arrêter les attaques

Injections SQL

Les injections SQL sont vraiment dévastatrices, mais peuvent être évitées en suivant quelques étapes simples.

Premièrement, assurez-vous que les privilèges utilisateurs dans la base de données sont limités (principe de moindre privilèges). Par exemple, les actions réalisées par un utilisateur front-office dans la base de données devraient être exécutées par un utilisateur n’ayant des droits que sur les tables liées aux fonctionnalités front-end. S’il n’y a pas besoin de supprimer les données d’une table spécifique, alors ne pas donner les droits de suppression à cet utilisateur sur cette table.

Ensuite, filtrer et nettoyer les données servant d’entrée aux instructions SQL (vous pouvez vous référer à la section filtrage et échappement des données de notre premier article).
Un moyen plus efficace pour se protéger des injections SQL (mais ne remplaçant pas le filtrage des données) est l’utilisation des “prepared statements” (requêtes paramétrées).
Voir comment implémenter les requêtes paramétrées : http://php.net/manual/fr/pdo.prepared-statements.php

Injections de commandes

Utiliser des exécutions de commandes via votre code PHP est très puissant, mais aussi très dangereux si les précautions nécessaires ne sont pas prises.
Il est donc recommandé de désactiver les fonctions dangereuses avec la directive disable_functions (dans le fichier php.ini).
De plus, une fois désactivées, ces fonctions ne pourront pas être utilisés par un pirate créant son propre code PHP via une potentielle autre faille.

disable_functions = show_source, exec, shell_exec, system, passthru, proc_open, popen, curl_exec, curl_multi_exec, parse_ini_file, show_source

Lors de l’utilisation de ces fonctions (si vous en avez absolument besoin), faites très attention aux paramètres passés en entrée. Vous devez vous assurer que les données sont strictement validées avec des listes blanches, et/ou filtrées.
Les commandes dans leur globalité ainsi que les arguments peuvent être échappés via les fonctions natives escapeshellcmd (http://php.net/manual/fr/function.escapeshellcmd.php) et escapeshellarg (http://php.net/manual/fr/function.escapeshellarg.php).

Vols de sessions

Les sessions reposent sur des identifiants de session.
Une attaque fréquente est la fixation de session, consistant à donner un identifiant de session à une victime avant que celle-ci ne s’identifie sur l’application, puis à utiliser ce même identifiant de session afin de récupérer la session de la victime.

Pour éviter de tels problèmes, quelques règles doivent être suivies :
ne pas accepter d’identifiant de session en provenance des URL ou des requêtes POST (directive session.use_only_cookies dans php.ini).
protéger les cookies de session avec les flags HttpOnly et Secure (paramètres session.cookie_secure et session.cookie_httponly dans php.ini)
donner une meilleure entropie aux identifiants de session, en paramétrant : session.entropy_file = /dev/urandom dans php.ini, sur les systèmes Linux.

Un point important est également de regénérer les identifiants de sessions à un moment critique : quand les utilisateurs se connectent.
Vous pouvez déclencher un renouvellement d’identifiant de session en appelant la fonction session_regenerate_id (http://php.net/manual/fr/function.session-regenerate-id.php).

Des éléments complémentaires peuvent être implémentées pour ajouter de la sécurité à différents niveaux (défense en profondeur) :
– garder une trace des dernières activités de l’utilisateur dans sa session, afin de détecter des activités suspectes sur des fonctions critiques.
– conserver le “user agent” dans la session et la vérifier à des moments clé.
– vérifier l’adresse IP n’est pas recommandé, étant donné qu’elle peut changer dynamiquement, par exemple sur les réseaux mobiles.

XSS

Protéger votre site contre les attaques XSS est assez simple, vous devez appliquer le principe “filter on input, escape on output” (voir notre article précédent).
Mais n’oubliez par d’appliquer ces vérifications sur tous les paramètres, y compris les paramètres cachés, les paramètres GET/POST, cookies et headers HTTP.

Une protection complémentaire peut être mise en place grâce aux HTTP headers. Celle-ci a été détaillée dans notre article “Sécurisez votre site web avec les headers HTTP” (inclure un lien).

Modification des paramètres

De nombreuses attaques s’appuient sur le fait que les URL et les formulaires peuvent être manipulés.
Attendez-vous à l’inattendu, et validez les paramètres avec des filtres et des listes blanches.