En-tête négligent

La classe fantôme : Armement de CVE-2025-32432 (Yii2 Container Injection) dans Craft CMS

Dans la hiérarchie des vulnérabilités modernes du web, Injection de dépendance (DI) Injection de conteneur se situe au sommet de la chaîne alimentaire. Elle est plus difficile à détecter que l'injection SQL, plus élégante que la corruption de la mémoire, et son impact est dévastateur.

La récente divulgation de CVE-2025-32432 ciblage Artisanat CMSet, par extension, l'objectif sous-jacent de la Cadre Yii2-nous rappelle brutalement que lorsque l'utilisateur contrôle l'instanciation de la classe, l'application appartient à l'attaquant. Alors que de nombreux scanners automatiques ont d'abord classé ce problème comme une "affectation de masse" ou un "problème de configuration" de faible gravité, les ingénieurs d'élite en sécurité le reconnaissent pour ce qu'il est vraiment : Exécution de code à distance (RCE) par le biais d'une logique de désérialisation d'objets non sécurisée.

Cet article fait une autopsie technique de la vulnérabilité. Nous irons au-delà de l'avis du fournisseur pour reconstruire la chaîne de gadgets, analyser les méthodes magiques PHP sous-jacentes, et démontrer pourquoi l'analyse sémantique pilotée par l'IA est le seul moyen viable de détecter ces failles logiques à grande échelle.

La classe fantôme : Armement de CVE-2025-32432 (Yii2 Container Injection) dans Craft CMS

L'architecture de l'échec : A l'intérieur du localisateur de services Yii2

Pour comprendre CVE-2025-32432, il faut d'abord comprendre le cœur architectural du framework Yii2 : yii\\\\NContainer.

Craft CMS s'appuie fortement sur le modèle Service Locator de Yii2 et sur le conteneur Dependency Injection pour gérer les dépendances des classes. Pour rendre le développement plus flexible, le conteneur permet aux développeurs de configurer les objets à l'aide de la fonction tableaux de configuration. Cette fonctionnalité est à l'origine de la vulnérabilité.

Le lien "CreateObject

Le puits critique de cette classe de vulnérabilité est Yii::createObject(). Cette méthode accepte un tableau de configuration dans lequel l'élément classe indique la classe PHP à instancier, et les clés suivantes définissent les propriétés publiques de cette instance.

PHP

// Utilisation légitime dans le code du backend du CMS Craft $object = Yii::createObject(['class' => 'app\models\User', 'username' => 'admin', 'role' => 'superuser' ]) ;

La vulnérabilité (CVE-2025-32432) est due au fait que certaines actions de contrôle dans le CMS Craft (souvent liées à l'enregistrement de la configuration des plugins ou à la gestion des brouillons) acceptent une entrée JSON brute à partir de la requête HTTP et la transmettent aveuglément à ce puits.

Le défaut de logique :

  1. Source : L'utilisateur envoie POST /api/v1/plugin-config avec un corps JSON.
  2. Débit : Le contrôleur décode le JSON dans un tableau PHP.
  3. L'évier : Le tableau est transmis à Yii::createObject($requestData).
  4. Résultat : L'attaquant définit le classetransformer l'injection de données en Injection d'objets.
Utilisation de CVE-2025-32432 (Yii2 Container Injection) dans Craft CMS

Construire la chaîne de la mort : La chasse aux gadgets

Dans l'exploitation de PHP, il est inutile de pouvoir instancier une classe à moins que cette classe fait quelque chose intéressant au cours de son cycle de vie. Nous avons besoin d'un Gadget.

Un gadget est une classe qui effectue des opérations sensibles (écriture de fichiers, exécution de commandes, requêtes de base de données) dans ses méthodes magiques (__construire, __destruct, Réveil, __toString) ou des méthodes d'initialisation (init). Étant donné que Craft CMS inclut l'ensemble de l'écosystème Yii2 et d'importantes bibliothèques de fournisseurs (Guzzle, Monolog, etc.), le paysage des gadgets est fertile.

Le gadget primaire : yii\\rest\NIndexAction

Dans le contexte de CVE-2025-32432, la chaîne de gadgets la plus fiable tire parti des éléments suivants yii\\rest\NIndexAction. Cette classe est conçue pour répertorier les modèles d'une API REST, mais elle possède une propriété spécifique : Vérifier l'accès.

Les Vérifier l'accès est destinée à contenir une fonction appelable pour le contrôle des autorisations. Cependant, comme nous contrôlons les valeurs de la propriété via le conteneur DI, nous pouvons transformer ceci en une fonction Primitive d'exécution du rappel.

La charge utile militarisée (PoC)

Vous trouverez ci-dessous une charge utile reconstituée dans le cadre de la démonstration de faisabilité. Cette structure JSON, lorsqu'elle est traitée par le point de terminaison vulnérable, déclenche un RCE.

JSON

{"action" : "save-config", "config" : { "class" : "yii\\\\rest\\\\IndexAction", "id": "rce_trigger", "controller" : { "class" : "yii\\\\web\\\\Controller", "id": "dummy_controller" }, "modelClass" : "yii\\\\base\\\\Model", "checkAccess": "system", "run" : "id ; uname -a ; cat /etc/passwd" } }

Flux d'exécution étape par étape :

  1. Instanciation : Le conteneur DI voit classe : yii\rest\\NIndexAction. Il utilise Reflection pour créer une instance de cette classe.
  2. Population de la propriété : Le conteneur parcourt les clés.
    • Il fixe $indexAction->checkAccess = 'system' (système).
    • Il instancie récursivement un contrôleur fictif (requis par IndexAction).
  3. Déclencher le piège : La plupart des composants Yii2 appellent init() ou exécuter() au cours de leur cycle de vie. Dans cette voie d'exploitation spécifique, la logique de l'application finit par invoquer l'action.
  4. Exécution du rappel : A l'intérieur IndexAction::run()le code vérifie si Vérifier l'accès est défini.PHP // Logique interne de yii\\rest\IndexAction if ($this->checkAccess) { call_user_func($this->checkAccess, $this->id, $params) ; }
  5. RCE : PHP exécute system('rce_trigger', ...)? Non, l'attaquant doit aligner les arguments. En manipulant les propriétés internes qui sont passées en tant qu'arguments au callback, l'attaquant atteint les objectifs suivants system('id ; ...').

Note : Les attaquants avancés enchaîneront avec yii\\caching\\FileCache pour écrire un webshell PHP persistant (par ex, shell.php) dans le webroot public (/web/assets/), ce qui permet de contourner les limites d'exécution éphémères.

Les raisons de l'échec des anciens scanners

La détection de CVE-2025-32432 est un cauchemar pour les outils traditionnels de test dynamique de la sécurité des applications (DAST).

  • Cécité syntaxique : La charge utile est un JSON syntaxiquement valide. Il ne contient pas de jetons SQL (OR 1=1) ou des vecteurs XSS (<script>). Les WAFs configurés pour les paramètres par défaut du Top 10 de l'OWASP laisseront généralement passer cela.
  • Cécité du contexte : Un scanner voit un objet JSON. Il ne comprend pas que la clé classe a une signification sémantique pour le cadre PHP dorsal. Pour un scanner, classe est juste un autre champ de données comme nom d'utilisateur ou courriel. Elle ne peut pas déduire la Instanciation des objets effet secondaire.

Détection pilotée par l'IA : L'avantage de la négligence

C'est ici que Penligent.ai représente un changement de paradigme dans les tests de sécurité offensifs. Penligent va au-delà de la recherche de motifs et utilise Analyse sémantique tenant compte du contexte.

  1. Cadre d'analyse des empreintes digitales et de la cartographie logique

Les agents IA de Penligent identifient d'abord la pile technologique sous-jacente (Craft CMS / Yii2). De manière cruciale, l'IA "connaît" les puits dangereux spécifiques à ce cadre. Elle comprend que dans Yii2, Yii::createObject est un point de contrôle critique, tout comme pickle.load l'est pour Python ou unserialize l'est pour le PHP générique.

  1. Sondage intelligent (Fuzzing avec intention)

Au lieu de pulvériser aveuglément des caractères aléatoires, Penligent construit des sondes logiques.

  • Sonde 1 : Injecter {"class" : "yii\\\\helpers\\\\VarDumper"}.
  • Observation : Le temps de réponse change-t-il ? Le message d'erreur fait-il référence à "VarDumper" ?
  • Déduction : Si l'application tente de charger la classe, l'IA confirme que l'élément classe est interprété par le conteneur DI.
  1. Vérification non destructive

Une fois le vecteur d'injection confirmé, Penligent n'a pas besoin d'exécuter rm -rf / pour prouver la vulnérabilité. Il peut générer une chaîne de gadgets bénigne (par exemple, une chaîne qui effectue simplement une recherche DNS vers un auditeur hors bande) pour prouver la capacité RCE avec une certitude de 100% et un risque nul pour l'infrastructure de production. Cela permet aux équipes de sécurité de valider les correctifs CVE-2025-32432 sans perturber les activités de l'entreprise.

Vulnérabilités connexes à fort impact

Pour bien comprendre le paysage des menaces, les ingénieurs en sécurité doivent établir une corrélation entre CVE-2025-32432 et les précédents historiques. Les mécanismes de Injection dans un conteneur ne sont pas propres à Craft CMS.

ID CVELogiciel cibleMécanisme technique
CVE-2023-41892Artisanat CMSRCE via ImageMagick dans la logique d'instanciation de l'objet dans le conditions paramètre.
CVE-2019-15488Cadre Yii2Désérialisation non sécurisée en yii\db\\BatchQueryResult Réveil méthode.

Ces vulnérabilités ont un ADN commun : La confiance dans les types d'entrées.

Remédiation et défense en profondeur

L'atténuation de CVE-2025-32432 nécessite une approche multicouche comprenant des corrections de code, un renforcement de la configuration et une protection de l'exécution.

1. Correction au niveau du code (la cause première)

La solution définitive consiste à appliquer Vérification stricte des types. Les développeurs ne doivent jamais transmettre des tableaux d'entrées utilisateur brutes directement à la fonction Yii::createObject.

  • Liste de refus : Désactiver explicitement l'option classe des tableaux d'entrée avant le traitement.
  • Allow-List : Si l'instanciation dynamique est nécessaire, valider la classe demandée par rapport à une liste blanche stricte et codée en dur de classes sûres.

PHP

// Implémentation sécurisée $config = json_decode($json, true) ; unset($config['class']) ; // Prévenir l'injection d'objets $object = Yii::createObject(array_merge(['class' => SafeClass::class], $config)) ;

2. Durcissement de l'exécution (php.ini)

Même si un attaquant instancie une classe, le RCE est impossible si les fonctions système sous-jacentes sont neutralisées. Configurez votre php.ini pour désactiver les fonctions d'exécution dangereuses :

Ini, TOML

disable_functions = system, exec, shell_exec, passthru, proc_open, popen, pcntl_exec

3. Rattrapage immédiat

Appliquez immédiatement la dernière mise à jour de Craft CMS. Le correctif du fournisseur pour CVE-2025-32432 introduit probablement un filtre au niveau du cadre de travail qui empêche le classe d'être honoré dans des actions spécifiques du contrôleur.

Conclusion

CVE-2025-32432 nous rappelle brutalement qu'à mesure que les cadres deviennent plus abstraits et plus puissants, ils introduisent des surfaces d'attaque logiques complexes. L'injection de conteneur est la "Injection SQL des années 2020-une faille non pas dans le code que vous écrivez, mais dans la façon dont vous configurez la magie du cadre.

Pour l'ingénieur en sécurité pur et dur, la leçon est claire : Validation des entrées doit aller au-delà des valeurs des données pour s'étendre aux données types et structures. Si vous permettez à un utilisateur de définir le structure d'un objet, vous avez déjà perdu la partie.

Références fiables

Partager l'article :
Articles connexes
fr_FRFrench