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-2026-25498

Crafting Chaos: RCE in Craft CMS via Yii2 Behavior Injection

Alon Barad
Alon Barad
Software Engineer

Feb 9, 2026·6 min read·49 visits

Executive Summary (TL;DR)

Authenticated RCE in Craft CMS (v4/v5). The `fieldLayout` parameter allows attackers to inject Yii2 Behaviors into object creation. By attaching `AttributeTypecastBehavior`, an attacker can trigger shell commands during server-side validation. Patch immediately to v5.8.22 or v4.16.18.

A high-severity Remote Code Execution (RCE) vulnerability exists in Craft CMS versions 4 and 5, specifically within the `assembleLayoutFromPost` method. The flaw stems from the unsafe usage of the Yii2 framework's dependency injection container, allowing authenticated administrators to inject malicious configuration arrays. By leveraging Yii2 'Behaviors,' attackers can achieve arbitrary code execution during object instantiation, effectively turning the CMS against its host server.

The Hook: Magic Methods, Magic Misery

If you've ever worked with the Yii2 framework (the engine purring underneath Craft CMS), you know it loves 'magic.' It has magic properties, magic events, and a dependency injection (DI) container that feels like wizardry. You pass it an array, and poof, it hands you a fully instantiated object with properties set, event listeners attached, and behaviors mixed in.

But here's the thing about magic: if you let a stranger cast the spells, you're going to have a bad time. CVE-2026-25498 is the result of exactly that—letting the user (even an authenticated one) dictate the configuration array passed to Craft::createObject().

This isn't a simple buffer overflow or a logic error. This is Object Injection via configuration. It's the PHP equivalent of handing someone a loaded gun and asking them to hold it while you tie your shoes. The specific vulnerability lies in how Craft CMS handles field layouts. When an admin saves a layout, the application takes a JSON blob from the request and feeds it directly into the object factory. If you know the right incantations (read: Yii2 internal classes), you can turn that JSON blob into a remote shell.

The Flaw: Trusting the 'Admin' Badge

The vulnerability lives in src/services/Fields.php, inside the assembleLayoutFromPost function. The purpose of this function is mundane: it reconstructs a Field Layout object based on data sent from the browser. It's supposed to take a JSON structure defining where fields go on the screen and hydrate a PHP object representing that layout.

Here is where the developer's optimism clashed with reality. The code assumed that because the user is an authenticated administrator, they wouldn't try to blow up the server.

Technically, the flaw is CWE-470: Use of Externally-Controlled Input to Select Classes or Code. The application accepts a raw JSON string from the fieldLayout POST parameter, decodes it into a PHP array, and passes that array straight into createLayout, which eventually calls Craft::createObject($config).

In Yii2, if a configuration array contains a key starting with as , the framework treats it as a Behavior attachment. Behaviors are mixins that can inject methods and properties into a class at runtime. If you control the behavior, you control the object's lifecycle. And if you control the lifecycle, you can hook into events like EVENT_AFTER_VALIDATE to execute code.

The Code: A Game of 'Spot the Difference'

Let's look at the smoking gun. This is the code running in src/services/Fields.php before the patch. Note the absolute lack of sanitization:

public function assembleLayoutFromPost(?string $namespace = null): FieldLayout
{
    $paramPrefix = $namespace ? rtrim($namespace, '.') . '.' : '';
    
    // VULNERABLE: Takes raw user input, decodes it, and creates an object.
    // There is no check on what keys exist in this JSON.
    $config = Json::decode(Craft::$app->getRequest()->getBodyParam($paramPrefix . 'fieldLayout'));
    
    return $this->createLayout($config);
}

The fix is painfully simple but highlights the root cause perfectly. The developers wrapped the input in ComponentHelper::cleanseConfig(). This helper method was actually introduced to fix a previous similar vulnerability (CVE-2025-68455). It seems they missed this specific spot during the first sweep—a classic case of 'Whack-a-Mole' security.

public function assembleLayoutFromPost(?string $namespace = null): FieldLayout
{
    $paramPrefix = $namespace ? rtrim($namespace, '.') . '.' : '';
    
    // PATCHED: The config is now scrubbed for dangerous keys before use.
    $config = ComponentHelper::cleanseConfig(
        Json::decode(Craft::$app->getRequest()->getBodyParam($paramPrefix . 'fieldLayout'))
    );
    
    return $this->createLayout($config);
}

What does cleanseConfig do? It recursively iterates through the array and nukes any key that starts with as (behaviors) or on (event handlers). It effectively neuters the magic, forcing the array to be treated as just data, not instructions.

The Exploit: Building the Gadget Chain

So, we can attach a behavior. Now what? We need a "gadget"—a class already present in the codebase that does something dangerous when we poke it. Enter yii\behaviors\AttributeTypecastBehavior.

This class is designed to automatically convert model attributes to specific types (e.g., integer, string). However, it allows you to define a callback for the conversion. If we tell it to convert the uid attribute using the passthru function, it will execute passthru($uid).

Here is the attack chain:

  1. Injection: We inject a configuration for AttributeTypecastBehavior using the as rce key.
  2. Trigger: We configure the behavior to run on typecastAfterValidate. This means the code executes automatically when the system tries to validate the layout object (which happens immediately upon save).
  3. Payload: We set the attributeTypes map to link a harmless looking property (like uid) to a system command executor (like passthru or system).
  4. Execution: We provide the command we want to run as the value of uid.

The Payload:

{
  "as rce": {
    "class": "yii\\behaviors\\AttributeTypecastBehavior",
    "attributeTypes": {
      "uid": "passthru"
    },
    "typecastAfterValidate": true
  },
  "uid": "id; uname -a"
}

When the server receives this, it creates the object, attaches the behavior, sets uid to id; uname -a, validates the object, triggers the event, and executes the shell command. The server response might hang or return the output, depending on how passthru interacts with the output buffer, but the damage is done.

The Impact: From Admin to God Mode

You might be thinking, "But you need to be an Admin to do this!" You are correct. This is an authenticated vulnerability (CVSS PR:H). However, in the real world, this is a catastrophic escalation.

Compromising a CMS admin account is often trivial. Admins reuse passwords. Admins get phished. Admins leave sessions open. In a standard scenario, an attacker with admin access can deface a site or steal customer data. With this vulnerability, they get root (or at least www-data) on the web server.

Once code execution is achieved, the attacker can:

  • Install a persistent webshell.
  • Pivot to the internal network.
  • Exfiltrate environment variables (AWS keys, database credentials).
  • Deploy ransomware.

This turns a "website problem" into an "infrastructure problem." It completely invalidates the security model of the application.

The Fix: Scrubbing the Input

If you are running Craft CMS 4 or 5, you need to update immediately. The fix is included in versions 5.8.22 and 4.16.18.

If you cannot update right now (perhaps you're locked in a change freeze or your dev team is on vacation), you can try to mitigate this at the WAF level. Block any POST request to /admin/* that contains the JSON substring "as followed by a generic alphanumeric string. However, WAF rules for JSON are notoriously brittle and prone to bypasses (e.g., using unicode escapes).

The real fix is the patch. The cleanseConfig method is the only reliable way to ensure that user input—even from trusted admins—cannot instantiate dangerous framework internals. This serves as a reminder to all PHP developers: Never pass user-controlled arrays to unserialize or Dependency Injection containers without strict allow-listing.

Official Patches

Craft CMSOfficial patch commit

Fix Analysis (1)

Technical Appendix

CVSS Score
8.6/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

Affected Systems

Craft CMS 4.x (< 4.16.18)Craft CMS 5.x (< 5.8.22)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Craft CMS
Pixel & Tonic
>= 4.0.0-RC1, < 4.16.184.16.18
Craft CMS
Pixel & Tonic
>= 5.0.0-RC1, < 5.8.225.8.22
AttributeDetail
CVE IDCVE-2026-25498
CVSS v4.08.6 (High)
CWECWE-470 (Unsafe Reflection)
Attack VectorNetwork (Authenticated)
ImpactRemote Code Execution (RCE)
Vulnerable Componentsrc/services/Fields.php
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.003Command and Scripting Interpreter: Windows Command Shell
Execution
T1203Exploitation for Client Execution
Execution
CWE-470
Use of Externally-Controlled Input to Select Classes or Code ('Unsafe Reflection')

The application uses externally-controlled input to select the class or code to be executed, which can be manipulated to execute malicious code.

Known Exploits & Detection

GitHub Security AdvisoryDetailed advisory with payload examples

Vulnerability Timeline

Initial fix for related CVE-2025-68455
2025-12-05
Patch committed for CVE-2026-25498
2026-01-09
Advisory Published
2026-02-09

References & Sources

  • [1]GHSA-7jx7-3846-m7w7
  • [2]Related Vulnerability (CVE-2025-68455)
Related Vulnerabilities
CVE-2025-68455

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

•14 minutes ago•CVE-2026-54269
5.3

CVE-2026-54269: Runtime Property Shadowing and Denial of Service in protobufjs

A property shadowing vulnerability exists in protobufjs where schema-derived names can collide with and overwrite runtime-critical internal helper properties. This issue leads to uncaught runtime exceptions and crash-based Denial of Service.

Alon Barad
Alon Barad
0 views•6 min read
•1 day ago•CVE-2025-6965
7.7

CVE-2025-6965: Remote Code Execution via Integer Truncation in SQLite Aggregate Parser

An integer truncation vulnerability (CWE-197) exists in SQLite before version 3.50.2 during the processing of aggregate queries with more than 32,767 distinct column references. This causes an internal 32-bit counter to truncate to a signed 16-bit integer, producing negative values that cause out-of-bounds heap operations in release builds.

Amit Schendel
Amit Schendel
12 views•6 min read
•2 days ago•CVE-2026-47291
9.8

CVE-2026-47291: Remote Code Execution in Windows HTTP.sys Kernel Driver

An integer overflow vulnerability in the Windows kernel-mode HTTP driver (HTTP.sys) allows an unauthenticated remote attacker to execute arbitrary code with kernel privileges or cause a Denial of Service via a specially crafted sequence of HTTP request headers.

Amit Schendel
Amit Schendel
22 views•8 min read
•2 days ago•CVE-2026-11822
7.8

CVE-2026-11822: Memory Corruption and Buffer Overflow in SQLite FTS5 Extension

A memory corruption vulnerability exists in the FTS5 (Full-Text Search 5) extension of SQLite prior to version 3.53.2. An attacker can construct a malicious database file containing corrupt FTS5 page data. Querying this database triggers out-of-bounds reads and heap-based buffer overflows, potentially causing a crash or arbitrary code execution.

Amit Schendel
Amit Schendel
7 views•5 min read
•2 days ago•CVE-2026-56350
6.3

CVE-2026-56350: SSO Enforcement Bypass in n8n via API Parameter Pollution / Mass Assignment

A mass assignment vulnerability (CWE-915) in n8n's self-service settings API endpoint (PATCH /me/settings) allows authenticated Single Sign-On (SSO) users to disable SSO enforcement for their accounts by injecting administrative parameters. This bypasses organizational identity provider controls and multi-factor authentication (MFA).

Amit Schendel
Amit Schendel
9 views•6 min read
•6 days ago•CVE-2026-55699
6.5

CVE-2026-55699: Arbitrary Directory Deletion via Path Traversal in pnpm globalBinDir Resolver

CVE-2026-55699 (also identified as GHSA-4gxm-v5v7-fqc4) is a critical path traversal and arbitrary directory deletion vulnerability in the pnpm package manager. The issue exists because the manifest validation process fails to prevent relative path segments within the package 'bin' keys. When a malicious package containing structured path traversal markers is globally installed and later manipulated, pnpm resolves the target paths through path.join() and passes the resolved paths to a recursive deletion function, resulting in arbitrary directory removal.

Amit Schendel
Amit Schendel
23 views•6 min read