Sécurité PHP expliquée · défensif
Injection d’objets PHP : de quoi s’agit-il et comment corriger
Passer des données contrôlées par l’utilisateur à unserialize() laisse l’attaquant choisir les objets que PHP crée. Le manuel PHP met en garde précisément contre cela.
Dernière mise à jour
De quoi s’agit-il
En désérialisant une chaîne, PHP recrée les objets décrits et peut appeler des méthodes magiques comme __wakeup() et __destruct(). Si la chaîne vient d’un cookie, d’un formulaire ou d’une requête API, l’attaquant peut choisir des classes déjà chargées par l’application ou ses bibliothèques et enchaîner leurs méthodes, jusqu’à l’écriture de fichiers ou l’exécution de code. MITRE la classe en CWE-502.
Comment le détecter
- Cherchez
unserialize(dans votre code et remontez l’origine de chaque argument. Tout chemin depuis$_GET,$_POST,$_COOKIE, les en-têtes, les fichiers envoyés ou un champ de base modifiable par les utilisateurs est un problème. - Vérifiez de même les extensions tierces et vieilles bibliothèques ; beaucoup d’anciens avis d’extensions CMS concernaient l’injection d’objets.
- L’analyse statique avec règles de sécurité (PHPStan, Psalm) et l’audit des dépendances (
composer audit) repèrent les paquets vulnérables connus.
Comment le corriger
- Utilisez
json_encode()etjson_decode()pour les données qui franchissent une frontière de confiance ; JSON ne peut pas créer d’objets PHP. - Si
unserialize()est inévitable, passez['allowed_classes' => false]ou une courte liste explicite. Le manuel PHP déconseille malgré tout les entrées non fiables. - Signez par HMAC les données sérialisées stockées côté client et vérifiez la signature avant décodage.
- Tenez frameworks et bibliothèques à jour pour éliminer les chaînes de gadgets connues.
Vérifications en lecture seule et modèles sûrs
# Find unserialize() calls that may receive request data (read-only)
grep -rnE "unserialize\s*\(" --include=*.php . | grep -vE "/vendor/|/tests?/"
// Safer: exchange data as JSON
$data = json_decode($input, true, 512, JSON_THROW_ON_ERROR);
// If unserialize() is unavoidable for trusted data, forbid objects
$data = unserialize($trusted, ['allowed_classes' => false]);allowed_classes => false suffit-il ?
Il bloque la création d’objets, donc le risque principal, mais le manuel PHP déconseille toujours de désérialiser des entrées non fiables. JSON est le choix par défaut le plus sûr.
Est-ce lié à PHP2Shell ?
Non. PHP2Shell est un bug du moteur PHP ; l’injection d’objets est un bug du code applicatif, présent même sur un PHP entièrement corrigé.
Autres classes de vulnérabilités PHP
- Inclusion de fichiers PHP (LFI/RFI) : de quoi s’agit-il et comment corrigerL’inclusion de fichiers survient quand une entrée utilisateur contrôle le chemin passé à include ou require, ce qui permet de lire des fichiers locaux (LFI) ou, avec allow_url_include activé, d’exécuter du code distant (RFI).
- SSRF en PHP : de quoi s’agit-il et comment corrigerLa falsification de requête côté serveur (SSRF) survient quand une application PHP récupère une URL contrôlée par l’utilisateur, ce qui permet d’atteindre des services internes ou des points de métadonnées cloud via votre serveur.
- XSS en PHP : de quoi s’agit-il et comment s’en protégerLe cross-site scripting (XSS) survient quand une page PHP affiche dans du HTML des données contrôlées par l’utilisateur sans échappement, si bien que le script d’un attaquant s’exécute dans le navigateur d’autres visiteurs.
- Exposition de phpinfo() : pourquoi c’est important et comment corrigerUne page phpinfo() publique révèle la version exacte de PHP, les modules chargés, les chemins et souvent des variables d’environnement ou des secrets, ce qui aide les attaquants à cibler des failles comme PHP2Shell.
Sources
Les liens externes quittent ce site. Nous n’hébergeons aucun code d’exploitation.
- unserialize() — PHP Manual
- json_decode() — PHP Manual
- PHP Object Injection — OWASP
- CWE-502: Deserialization of Untrusted Data — MITRE CWE