In the hierarchy of modern web vulnerabilities, Injection de dépendance (DI) Injection de conteneur sits at the very apex of the food chain. It is harder to detect than SQL Injection, more elegant than Memory Corruption, and devastating in its impact.
The recent disclosure of CVE-2025-32432 ciblage Artisanat CMS—and by extension, the underlying Cadre Yii2—serves as a brutal reminder: when user input controls class instantiation, the application belongs to the attacker. While many automated scanners initially triaged this as a low-severity “Mass Assignment” or “Configuration Issue,” elite security engineers recognize it for what it truly is: Exécution de code à distance (RCE) via insecure object deserialization logic.
This article performs a technical autopsy of the vulnerability. We will move beyond the vendor advisory to reconstruct the gadget chain, analyze the underlying PHP magic methods, and demonstrate why AI-driven semantic analysis is the only viable way to catch these logic flaws at scale.

The Architecture of Failure: Inside the Yii2 Service Locator
To understand CVE-2025-32432, you must first understand the architectural heart of the Yii2 framework: yii\\\\NContainer.
Craft CMS relies heavily on Yii2’s Service Locator pattern and Dependency Injection container to manage class dependencies. To make development flexible, the container allows developers to configure objects using configuration arrays. This feature is the root cause of the vulnerability.
The “CreateObject” Sink
The critical sink in this vulnerability class is Yii::createObject(). This method accepts a configuration array where the classe key dictates what PHP class to instantiate, and subsequent keys define the public properties of that instance.
PHP
// Legitimate usage in Craft CMS backend code $object = Yii::createObject([ 'class' => 'app\\models\\User', 'username' => 'admin', 'role' => 'superuser' ]);
The vulnerability (CVE-2025-32432) arises because specific Controller Actions in Craft CMS (often related to plugin configuration saving or draft handling) accept raw JSON input from the HTTP request and pass it blindly into this sink.
The Logic Flaw:
- Source : User sends
POST /api/v1/plugin-configwith JSON body. - Débit : The controller decodes the JSON into a PHP array.
- L'évier : The array is passed to
Yii::createObject($requestData). - Résultat : The attacker defines the
classe, transforming data injection into Injection d'objets.

Constructing the Kill Chain: The Gadget Hunt
In PHP exploitation, being able to instantiate a class is useless unless that class does something interesting during its lifecycle. We need a Gadget.
A Gadget is a class that performs sensitive operations (file writes, command execution, database queries) in its magic methods (__construire, __destruct, Réveil, __toString) or initialization methods (init). Since Craft CMS includes the entire Yii2 ecosystem and massive vendor libraries (Guzzle, Monolog, etc.), the gadget landscape is fertile.
The Primary Gadget: yii\\rest\NIndexAction
In the context of CVE-2025-32432, the most reliable gadget chain leverages yii\\rest\NIndexAction. This class is designed to list models for a REST API, but it has a specific property: Vérifier l'accès.
Les Vérifier l'accès property is intended to hold a callable function for permission checking. However, because we control the property values via the DI container, we can turn this into a Callback Execution Primitive.
The Weaponized Payload (PoC)
Below is a reconstructed Proof of Concept (PoC) payload. This JSON structure, when processed by the vulnerable endpoint, triggers 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" } }
Step-by-Step Execution Flow:
- Instantiation: The DI container sees
class: yii\\rest\\IndexAction. It uses Reflection to create an instance of this class. - Property Population: The container iterates through the keys.
- It sets
$indexAction->checkAccess = 'system'. - It recursively instantiates a
dummy_controller(required byIndexAction).
- It sets
- Triggering the Trap: Most Yii2 components call
init()ouexécuter()during their lifecycle. In this specific exploit path, the application logic eventually invokes the action. - Callback Execution: Inside
IndexAction::run(), the code checks ifVérifier l'accèsis set.PHP// Internal logic of yii\\rest\\IndexAction if ($this->checkAccess) { call_user_func($this->checkAccess, $this->id, $params); } - RCE: PHP executes
system('rce_trigger', ...)? No, the attacker must align the arguments. By manipulating internal properties that are passed as arguments to the callback, the attacker achievessystem('id; ...').
Note: Advanced attackers will chain this with yii\\caching\\FileCache gadgets to write a persistent PHP webshell (e.g., shell.php) into the public webroot (/web/assets/), bypassing ephemeral execution limits.
Why Legacy Scanners Fail
Detecting CVE-2025-32432 is a nightmare for traditional Dynamic Application Security Testing (DAST) tools.
- Syntax Blindness: The payload is syntactically valid JSON. It does not contain SQL tokens (
OR 1=1) or XSS vectors (<script>). WAFs configured for OWASP Top 10 defaults will usually let this pass. - Cécité du contexte : A scanner sees a JSON object. It does not understand that the key
classehas semantic meaning to the backend PHP framework. To a scanner,classeis just another data field likeusernameouemail. It cannot infer the Object Instantiation side effect.
Détection pilotée par l'IA : L'avantage de la négligence
C'est ici que Penligent.ai represents a paradigm shift in offensive security testing. Penligent moves beyond pattern matching to employ Context-Aware Semantic Analysis.
- Framework Fingerprinting & Logic Mapping
Penligent’s AI agents first identify the underlying technology stack (Craft CMS / Yii2). Crucially, the AI “knows” the dangerous sinks specific to this framework. It understands that in Yii2, Yii::createObject is a critical control point, just as pickle.load is for Python or unserialize is for generic PHP.
- Intelligent Probing (Fuzzing with Intent)
Instead of blindly spraying random characters, Penligent constructs Logic Probes.
- Probe 1: Inject
{"class": "yii\\\\helpers\\\\VarDumper"}. - Observation: Does the response time change? Does the error message reference “VarDumper”?
- Inference: If the application attempts to load the class, the AI confirms that the
classeparameter is being interpreted by the DI container.
- Non-Destructive Verification
Once the injection vector is confirmed, Penligent does not need to execute rm -rf / to prove the vulnerability. It can generate a benign gadget chain (e.g., one that simply performs a DNS lookup to an out-of-band listener) to prove RCE capability with 100% certainty and zero risk to the production infrastructure. This allows security teams to validate CVE-2025-32432 patches without disrupting business operations.
Related High-Impact Vulnerabilities
To fully understand the threat landscape, security engineers should correlate CVE-2025-32432 with historical precedents. The mechanics of Injection dans un conteneur are not unique to Craft CMS.
| ID CVE | Target Software | Technical Mechanism |
|---|---|---|
| CVE-2023-41892 | Artisanat CMS | RCE via ImageMagick object instantiation logic in the conditions paramètre. |
| CVE-2019-15488 | Cadre Yii2 | Insecure deserialization in yii\\db\\BatchQueryResult Réveil méthode. |
These vulnerabilities share a common DNA: The Trust of Input Types.
Remediation and Defense-in-Depth
Mitigating CVE-2025-32432 requires a multi-layered approach involving code fixes, configuration hardening, and runtime protection.
1. Code-Level Fix (The Root Cause)
The definitive fix is to enforce Strict Type Checking. Developers must never pass raw user input arrays directly to Yii::createObject.
- Deny-List: Explicitly unset the
classekey from input arrays before processing. - Allow-List: If dynamic instantiation is necessary, validate the requested class against a strict, hardcoded whitelist of safe classes.
PHP
// Secure Implementation $config = json_decode($json, true); unset($config['class']); // Prevent Object Injection $object = Yii::createObject(array_merge(['class' => SafeClass::class], $config));
2. Runtime Hardening (php.ini)
Even if an attacker instantiates a class, RCE is impossible if the underlying system functions are neutered. Configure your php.ini to disable dangerous execution functions:
Ini, TOML
disable_functions = system, exec, shell_exec, passthru, proc_open, popen, pcntl_exec
3. Immediate Patching
Apply the latest Craft CMS update immediately. The vendor patch for CVE-2025-32432 likely introduces a framework-level filter that prevents the classe parameter from being honored in specific controller actions.
Conclusion
CVE-2025-32432 is a stark reminder that as frameworks become more abstract and powerful, they introduce complex logical attack surfaces. Container Injection is the “SQL Injection of the 2020s”—a flaw not in the code you write, but in how you configure the magic of the framework.
For the hardcore security engineer, the lesson is clear: Input Validation must extend beyond data values to data types et structures. If you allow a user to define the structure of an object, you have already lost the game.

