
Preuve de concept locale sécurisée pour la vulnérabilité d'injection d'objet PHP Cotonti CommentsWidget (CAN-2026-2035973 / CVE-2026-71294).
Preuve de concept locale sûre pour le problème d'injection d'objet PHP identifié dans l'implémentation CommentsWidget de Cotonti.
plugins/comments/inc/CommentsWidget.phpLe chemin de code vulnérable accepte le paramètre GET ci et transmet des données contrôlées par l'attaquant via base64_decode() dans le unserialize() de PHP sans restreindre les classes pouvant être instanciées.
Conceptuellement, l'opération vulnérable est :
$ci = @unserialize(base64_decode($ci));
Lorsqu'un objet sérialisé est fourni, PHP peut instancier la classe contrôlée par l'attaquant et invoquer des méthodes magiques telles que . Dans une application plus large, cela peut devenir dangereux lorsque des classes gadget appropriées sont disponibles.
__wakeup()Le correctif soumis modifie la désérialisation en :
$ci = @unserialize(base64_decode($ci), ['allowed_classes' => false]);
et valide que la valeur résultante possède la structure de tableau attendue avant de l'utiliser.
poc.php effectue trois tests locaux :
unserialize() sans restriction instancie DangerousGadget et déclenche sa méthode __wakeup().allowed_classes => false empêche l'instanciation de la classe gadget et donc l'effet de bord de __wakeup().La PoC utilise /tmp/pwned_by_cotonti_poc.txt uniquement comme sentinelle inoffensive montrant que __wakeup() s'est exécuté. Elle n'exécute pas de commande système. La chaîne id && whoami n'existe que comme valeur de remplacement dans la propriété command du gadget.
serialize() / unserialize()Aucune installation de Cotonti n'est requise car le comportement de désérialisation vulnérable et corrigé est reproduit directement.
Depuis le répertoire du dépôt :
php poc.php
La sortie attendue est similaire à :
[!] DangerousGadget::__wakeup() triggered
[TEST 1] VULNERABLE: __wakeup() executed during unrestricted unserialize().
[TEST 2] FIXED: object instantiation was blocked; no sentinel was created.
[TEST 3] FIXED: invalid serialized structure rejected by validation.
Summary:
- Vulnerable path allows a serialized attacker-controlled object to be instantiated and invokes __wakeup().
- Fixed path uses allowed_classes=false, preventing the gadget class from being instantiated.
- Structural validation rejects values that do not match the expected array shape.
- No real command execution is performed by this PoC; the command property is only a placeholder.
Le script supprime son fichier sentinelle avant de se terminer.
Ne désérialisez pas de données contrôlées par l'attaquant avec le unserialize() PHP sans restriction.
Pour ce chemin de code, l'atténuation démontrée consiste à désactiver l'instanciation de classes :
unserialize($data, ['allowed_classes' => false]);
La valeur désérialisée doit également être validée par rapport à la structure exacte attendue par l'application avant que son contenu ne soit utilisé.
Ce dépôt est destiné à la recherche en sécurité, à la vérification et aux tests défensifs. Exécutez la PoC uniquement dans des environnements que vous possédez ou que vous êtes explicitement autorisé à tester. Ne l'utilisez pas pour cibler des systèmes sans autorisation.
Harsh Raj Singhania — recherche sur la vulnérabilité, preuve de concept et divulgation.