CVE-2026-82222 est une injection d'objets PHP critique, exploitable sans authentification, dans GiveWP, un plugin WordPress de dons et de collecte de fonds comptant plus de 100 000 installations. Toutes les versions jusqu'à 4.16.7.1 sont concernées. La faille est notée CVSS 10.0 et mène à une exécution de code à distance. Udin Chan l'a signalée via Patchstack le 28/07/2026. La version 4.16.7.2 la corrige.
if ( self::containsPhpIncompleteClass( $unserializedData ) ) {
return false; // 4.16.6 returned $data here, re-arming the payload
}L'exploitation enchaîne trois failles. D'abord, le helper safeUnserialize() dans src/Helpers/Utils.php appelle unserialize() avec allowed_classes à false. Cette option ne supprime pas les objets. Elle les convertit en placeholders __PHP_Incomplete_Class qui conservent le nom de classe d'origine et toutes les propriétés. Lorsqu'un tel placeholder est resérialisé, PHP réémet les octets d'origine. La charge utile survit donc intacte.
Ensuite, le flux de donation dans includes/process-donation.php fait passer les données du compte par ce helper et les stocke dans la table wp_give_sessions. L'attaquant dépose un gadget sérialisé dans son propre champ last_name via profile.php. Lors de la soumission du don, la valeur traverse safeUnserialize() et est écrite dans la table de sessions. La lecture suivante appelle unserialize() sans garde-fou, et l'objet gadget reprend vie.
Enfin, la gadget chain combine la bibliothèque TCPDF livrée avec le plugin et les classes Give\TestData. L'attaquant contrôle la propriété tableau loadedProviders de l'objet désérialisé. À la destruction de l'objet, TCPDF::__destruct() appelle _destroy(), qui invoque une méthode indéfinie et aboutit dans la méthode magique __call(). Celle-ci transmet la valeur directement à call_user_func_array() sans validation. En définissant loadedProviders à system, on exécute des commandes arbitraires avec les droits du serveur web.
La chaîne exige un compte, et GiveWP le fournit gratuitement. Le gestionnaire give_action=user_register ignore l'option WordPress users_can_register. N'importe qui peut créer un compte et recevoir un cookie d'authentification, même lorsque l'inscription est désactivée. La version 4.16.6 a ajouté un nonce, mais les nonces des visiteurs non connectés sont identiques sur tout le site, et le shortcode [give_register] en émet un sur toute page publique. Il suffit de le récolter une fois.
La séquence complète : s'inscrire via give_action=user_register, placer le gadget dans last_name, récupérer un nonce de don avec action=give_donation_form_nonce, soumettre un don via action=give_process_donation en omettant give_last. Le serveur écrit le gadget dans wp_give_sessions avant de renvoyer HTTP 500. Toute requête frontale suivante avec le même cookie déclenche désérialisation, destruction et system(). La sortie est renvoyée dans la réponse HTTP. Jusqu'à 4.16.5.1, une installation par défaut suffit. Les versions 4.16.6 à 4.16.7.1 réduisent la surface mais restent exploitables dans des conditions courantes comme les formulaires legacy ou l'Option-Based Form Editor.
Le correctif 4.16.7.2 rompt la chaîne en cinq points. safeUnserialize() renvoie désormais false lorsqu'il détecte une __PHP_Incomplete_Class ; la tentative de 4.16.6 renvoyait la chaîne brute, ce qui réarmait la charge utile. process-donation.php rejette les dons contenant des données sérialisées dans les champs de nom, et le fallback usermeta passe par give_clean(). Les trois puits de lecture class-give-session.php, class-give-db-sessions.php et class-give-donor-wall.php passent désormais explicitement allowed_classes à false ; le donor wall était le plus critique car le shortcode public [give_donor_wall] était accessible anonymement. ProviderForwarder::__call() vérifie désormais le provider résolu avant de l'appeler. Les métas de nom donor et billing passent par sanitize_text_field(). Une migration SanitizeSerializedObjectPayloads parcourt usermeta, give_donormeta, give_donationmeta et give_sessions en remplaçant les objets imbriqués par des chaînes vides pour purger les charges plantées avant la mise à jour.
Le contournement d'inscription reste ouvert dans 4.16.7.2, mais sans l'injection d'objets il ne mène plus à l'exécution de code. Patchstack le traite comme un problème de contrôle d'accès distinct. Les administrateurs doivent mettre à jour immédiatement, vérifier que la migration d'assainissement a bien été exécutée, contrôler les quatre tables à la recherche de charges résiduelles et envisager de bloquer give_action=user_register par une règle WAF si l'inscription n'est pas nécessaire.




Commentaires
Pas encore de commentaire — écris le premier.
Lance la discussion
Pas de compte ni de mot de passe — saisis simplement ton adresse e-mail et nous t’envoyons un lien de connexion à usage unique. Première visite ? Tout se met en place automatiquement.
Ton évaluation sera appliquée automatiquement après ta connexion.
Vérifie ta boîte mail
Nous avons envoyé un lien de connexion à …. Ouvre-le sur cet appareil — cet onglet te connectera automatiquement.
Rien reçu ? Vérifiez le dossier spam — et marquez le message « Non spam » pour qu'il arrive directement la prochaine fois.