CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-32432

Craft CMS: The Art of Array Injection (CVE-2025-32432)

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 26, 2026·5 min read·185 visits

Executive Summary (TL;DR)

Unauthenticated attackers can achieve RCE on Craft CMS by sending a malicious JSON packet to the `generate-transform` endpoint. The flaw exploits PHP's type juggling and Yii2's behavior injection logic.

A critical unauthenticated Remote Code Execution (RCE) vulnerability in Craft CMS that arises from improper input validation in the asset transformation engine. By injecting an array into the `handle` parameter, attackers can manipulate Yii2 framework behaviors to instantiate arbitrary PHP objects, leading to a full system compromise. This vulnerability bypasses previous fixes for CVE-2023-41892 and is actively exploited in the wild.

The Hook: When "Handle" isn't a String

In the world of web application security, the most dangerous assumptions are often the simplest ones. In Craft CMS, the assumption was that a request parameter named handle would always be a string—a filename, a slug, a simple identifier. But this is PHP, a language that happily treats everything as a suggestion rather than a rule.

CVE-2025-32432 is what happens when you trust user input to define the structure of your objects. It lives in the actionGenerateTransform method of the AssetsController. This endpoint is designed to generate image thumbnails on the fly. It's publicly accessible because, logically, you want your website visitors to see images without logging in.

However, this endpoint takes the handle parameter and passes it straight into the deep magic of the Yii2 framework (on which Craft is built). If an attacker decides that handle isn't a string like "thumbnail", but rather a complex associative array, the application doesn't complain. It attempts to parse it. This is where the door to the kingdom is left unlocked.

The Flaw: Yii2 Magic and Behavior Injection

To understand this exploit, you have to understand the specific flavor of "magic" used by Yii2. The framework has a concept called Behaviors. Think of them as dynamic mixins—ways to attach methods and properties to a class at runtime.

When Craft CMS processes the handle, it eventually calls App::configure($object, $properties). This function iterates through the input array. If it sees a key that starts with as , it treats it as a request to attach a Behavior. For example, "as behaviorName": { ... }.

> [!NOTE] > This is a classic "Object Injection via Configuration" pattern. The application blindly trusts the configuration array provided by the user.

The vulnerability is a logic flaw in how Yii2 validates these behaviors. It checks if the configuration array contains a class key that implements the Behavior interface. That sounds safe, right?

Wrong.

The framework's object factory (Yii::createObject) has a quirk: if you provide both a class key AND a __class key, it uses class for validation checks but uses __class for the actual object instantiation. This allows an attacker to pass the validation check with a harmless class, while simultaneously instantiating a malicious gadget class using __class.

The Exploit: From Array to RCE

So how do we turn "I can create an object" into "I own your server"? We need a Gadget Chain. The researchers (and the attackers known as "Mimo") found two distinct paths.

Path A: The One-Shot (PHP Info) This method uses the GuzzleHttp\Psr7\FnStream class. This class has a destructor (__destruct) that calls a function defined in the _fn_close property.

By injecting an array defining a behavior with __class set to FnStream and _fn_close set to phpinfo, the attacker triggers the function the moment the request ends and the object is destroyed.

Path B: The Heavy Hitter (Full RCE) This is where it gets cynical. To execute arbitrary commands, attackers use a two-step process involving Local File Inclusion (LFI).

  1. Seeding: The attacker hits a URL like /admin/dashboard?x=<?php system($_GET['cmd']); ?>. Craft CMS forces a login redirect but logs the "return URL" (containing the PHP payload) into a session file on the disk (e.g., /var/lib/php/sessions/sess_...).
  2. Triggering: The attacker sends the exploit payload to generate-transform. They instantiate yii\rbac\PhpManager. This class has an init() method (called automatically) that includes a file specified by the itemFile property. The attacker sets itemFile to the path of the dirty session file.

Boom. The session file is included, the PHP code inside it executes, and the server runs the command.

The Code: One Line to Rule Them All

The fix for this critical vulnerability is embarrassingly simple. It highlights just how fragile loose typing can be.

The patch (Commit e1c85441fa47eeb7c688c2053f25419bc0547b47) simply enforces that the input is actually a string before letting it anywhere near the image transformation logic.

// src/controllers/AssetsController.php
 
public function actionGenerateTransform(): Response
{
    $assetId = $this->request->getRequiredBodyParam('assetId');
    $handle = $this->request->getRequiredBodyParam('handle');
 
    // THE FIX: explicitly check the type
    if (!is_string($handle)) {
        throw new BadRequestHttpException('Invalid transform handle.');
    }
 
    // ... existing logic ...
    $transform = ImageTransforms::normalizeTransform($handle);
}

Before this if statement existed, $handle could be anything. After this patch, the exploit chain is dead on arrival because the array injection is rejected immediately. It is a stark reminder: Always validate your input types, not just their existence.

The Impact: Why This Matters

This isn't just a theoretical bug. It is being actively exploited by groups like "Mimo" to deploy malware and ransomware. Because the endpoint is unauthenticated, every single exposed Craft CMS install within the affected version range is vulnerable.

The attacker doesn't need to guess passwords or brute force login forms. They just need to send one POST request. The EPSS score is in the 99th percentile for a reason. If you run Craft CMS 3, 4, or 5 and haven't updated since April 2025, assume you are compromised.

Furthermore, this was an "incomplete fix" scenario (fixing CVE-2023-41892). This means threat actors were already looking at this code, knew it was fragile, and likely found this bypass long before the defenders did.

Official Patches

Craft CMSOfficial Changelog

Fix Analysis (1)

Technical Appendix

CVSS Score
10.0/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L
EPSS Probability
80.36%
Top 1% most exploited
15,000
via Shodan

Affected Systems

Craft CMS 3.xCraft CMS 4.xCraft CMS 5.x

Affected Versions Detail

Product
Affected Versions
Fixed Version
Craft CMS
Pixel & Tonic
3.0.0-RC1 - 3.9.143.9.15
Craft CMS
Pixel & Tonic
4.0.0-RC1 - 4.14.144.14.15
Craft CMS
Pixel & Tonic
5.0.0-RC1 - 5.6.165.6.17
AttributeDetail
CWE IDCWE-94 (Code Injection)
CVSS Score10.0 (Critical)
Attack VectorNetwork (Unauthenticated)
EPSS Score0.8036 (99.09%)
Exploit StatusActive / Weaponized
ImpactRemote Code Execution (RCE)

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1203Exploitation for Client Execution
Execution
T1059.006Command and Scripting Interpreter: Python
Execution
CWE-94
Code Injection

Improper Control of Generation of Code ('Code Injection')

Known Exploits & Detection

NucleiNuclei template for detecting CVE-2025-32432 via phpinfo trigger
SensePostDetailed writeup of the Mimo exploitation campaign

Vulnerability Timeline

Exploitation detected in the wild
2025-02-01
Patch released by Craft CMS
2025-04-10
CVE-2025-32432 published
2025-04-25

References & Sources

  • [1]GitHub Advisory
  • [2]Mimo Campaign Analysis
Related Vulnerabilities
CVE-2023-41892

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•3 days ago•CVE-2026-115895
8.8

CVE-2026-115895: Code Injection via Unsanitized Import Alias in Happy DOM ECMAScript Module Compiler

CVE-2026-115895 is a high-severity code injection vulnerability (CWE-94) in the happy-dom npm package prior to version 21.0.4. The vulnerability exists within the ECMAScriptModuleCompiler component, which transforms ECMAScript module syntax into executable Node.js functions when JavaScript evaluation is enabled. Due to an incomplete fix for CVE-2026-33943, the compiler failed to validate local named import aliases against legal JavaScript identifier rules. Attackers supplying crafted module imports—specifically utilizing destructuring default initializers alongside JSON module attributes—can inject arbitrary JavaScript expressions directly into the host Node.js runtime context.

Amit Schendel
Amit Schendel
8 views•10 min read
•3 days ago•CVE-2026-115883
6.0

CVE-2026-115883: Cross-Namespace Access via Dot-Delimited Labels in LangGraph Postgres and SQLite Stores

An improper input validation and authorization bypass vulnerability exists in the LangGraph storage layer affecting langgraph, langgraph-checkpoint-postgres, and langgraph-checkpoint-sqlite. Because relational store implementations serialize namespace tuples into dot-delimited strings without validating labels on read, search, delete, and batch operations, an attacker who controls a namespace label can inject periods (.) to traverse namespace boundaries and access, modify, or delete data belonging to other namespaces.

Amit Schendel
Amit Schendel
9 views•9 min read
•3 days ago•CVE-2026-115886
6.5

CVE-2026-115886: Unauthenticated Server-Side Request Forgery and Unsafe Reflection in MLflow Scorer Evaluation Endpoints

CVE-2026-115886 (GHSA-2wqp-q3c6-ccj5) is a Server-Side Request Forgery (SSRF) and Unsafe Reflection vulnerability in MLflow versions 3.12.0rc0 prior to 3.17.0. Unauthenticated REST API endpoints accept serialized third-party scorer JSON payloads that are dynamically deserialized and reflectively instantiated without sanitizing constructor keyword arguments. When optional dependencies such as trulens and trulens-providers-litellm are installed, attackers can inject egress-steering arguments into the scorer payload, forcing the MLflow server to dispatch outbound HTTP requests to arbitrary internal destinations or cloud metadata services.

Alon Barad
Alon Barad
13 views•10 min read
•3 days ago•CVE-2026-113872
7.5

CVE-2026-113872: Unauthenticated Process Crash in Express Multer via Late Busboy Stream Resumption

CVE-2026-113872 (GHSA-q7qp-rjg7-q26m) is a high-severity denial-of-service vulnerability affecting the multer multipart/form-data upload middleware for Node.js and Express in versions 2.0.0 through 2.4.0. When an endpoint is configured to accept multiple files using an asynchronous fileFilter callback, a crafted, truncated multipart HTTP request can trigger an unhandled error event on the underlying busboy stream parser after request teardown has already completed. Because all error listeners are stripped during teardown, Node.js treats the resulting error event as an uncaught exception and immediately terminates the server process.

Amit Schendel
Amit Schendel
10 views•12 min read
•3 days ago•CVE-2026-115897
2.1

CVE-2026-115897: Cross-Site Scripting via Function Body Boundary Bypass in serialize-javascript

CVE-2026-115897 (also tracked as GHSA-m5mm-p8h7-m29v and aliased as CVE-2026-115754) is a Cross-Site Scripting (XSS) vulnerability in the Yahoo serialize-javascript npm package prior to version 7.1.3. The flaw exists in the regular expression used by escapeFunctionBody() to neutralize HTML script closing tags within serialized JavaScript functions. Because function bodies are sanitized in isolation before structural formatting is applied, a function whose string representation terminates directly with the sequence '</script' bypasses the positive lookahead check. When combined with serialization formatting options that introduce whitespace delimiters and a subsequent property that supplies a closing bracket, an attacker can prematurely terminate an enclosing HTML <script> block and inject arbitrary HTML or JavaScript into the rendered document.

Amit Schendel
Amit Schendel
7 views•13 min read
•3 days ago•CVE-2026-109841
5.9

CVE-2026-109841: Subresource Integrity Verification Bypass in Node.js Undici

CVE-2026-109841 is a Subresource Integrity (SRI) verification bypass vulnerability in undici, the official HTTP/1.1 and HTTP/2 client library for Node.js that powers the global fetch() implementation. The flaw stems from improper handling of case sensitivity (CWE-178) when validating cryptographic hash algorithm tokens within SRI metadata. Because undici compared incoming algorithm identifiers against a strictly lowercase set without prior ASCII-lowercase normalization, valid uppercase or mixed-case tokens such as SHA256- or Sha384- were treated as unrecognized algorithms and discarded. Under SRI forward-compatibility rules, discarding all provided tokens results in an empty integrity list, causing undici to fail open and accept tampered HTTP response bodies without cryptographic verification.

Alon Barad
Alon Barad
17 views•9 min read