Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-71294

CVE-2026-71294: Cotonti CMS Comments Plugin RCE Flaw

CVE-2026-71294 is an unsafe deserialization flaw in Cotonti CMS Comments plugin allowing authenticated members to inject malicious PHP objects leading to remote code execution. This article covers technical details, exploitation.

Published:

CVE-2026-71294 Overview

CVE-2026-71294 is a PHP Object Injection vulnerability in the Comments plugin of Cotonti CMS. The flaw stems from calls to unserialize() on user-supplied, base64-decoded input without the allowed_classes restriction. Any authenticated member with write access to comments can reach the vulnerable sinks in CreateAction.php and EditAction.php. Successful exploitation instantiates arbitrary PHP classes loaded by Cotonti, enabling POP-chain attacks. Researchers demonstrated a working chain using Cotonti's own MySQL_cache class to trigger attacker-controlled INSERT INTO cot_cache operations through the __destruct()->flush() sequence. Further impact, including potential remote code execution, depends on other gadget chains present in a given installation [CWE-502].

Critical Impact

Authenticated attackers can inject arbitrary serialized PHP objects, achieving database write primitives and potentially remote code execution through available gadget chains.

Affected Products

  • Cotonti CMS Comments plugin (plugins/comments/controllers/actions/CreateAction.php)
  • Cotonti CMS Comments plugin (plugins/comments/controllers/actions/EditAction.php)
  • Cotonti installations with default Auth_members => 'RW' in plugins/comments/comments.setup.php

Discovery Timeline

  • 2026-08-05 - CVE-2026-71294 published to NVD
  • 2026-08-05 - Last updated in NVD database

Technical Details for CVE-2026-71294

Vulnerability Analysis

The Comments plugin exposes two deserialization sinks reachable by ordinary authenticated members. In CreateAction.php, the ci POST parameter is retrieved via cot_import('ci', 'P', 'TXT'), which performs only trim-based sanitization. The value is then passed directly to unserialize(base64_decode($ci)) without the allowed_classes option.

In EditAction.php, the cb parameter follows the same pattern inside prepareComeBack(), invoking unserialize(base64_decode($this->comeback)). This sink is reachable by any member editing their own comment. A third sink in DeleteAction.php uses the identical pattern but sits behind an admin-only authorization check, limiting its reachability.

Researchers confirmed exploitation using Cotonti's MySQL_cache class. A crafted serialized MySQL_cache instance, once deserialized and later garbage-collected, triggers its __destruct() method. That in turn calls flush(), producing an attacker-controlled INSERT INTO cot_cache statement with attacker-chosen row values.

Root Cause

The root cause is unrestricted PHP object deserialization on attacker-controlled input [CWE-502]. Calling unserialize() without the allowed_classes parameter permits instantiation of any class loaded in the Cotonti runtime. Combined with trim-only input sanitization, this exposes every magic method (__destruct, __wakeup, __toString) of loaded classes as a potential gadget entry point.

Attack Vector

An authenticated member with the default RW permission on comments crafts a serialized PHP object, base64-encodes it, and submits it as the ci parameter when creating a comment or the cb parameter when editing one. The server decodes and deserializes the payload, instantiating the attacker's chosen class. When the object is destroyed, its magic methods execute, driving the POP chain. The demonstrated MySQL_cache gadget confirms arbitrary SQL INSERT operations; further gadgets in a given installation may extend the impact to file write or code execution.

See the Cotonti CreateAction source for the vulnerable sink.

Detection Methods for CVE-2026-71294

Indicators of Compromise

  • Unexpected rows in the cot_cache table containing attacker-controlled keys or values not produced by legitimate cache operations.
  • HTTP POST requests to comment create or edit endpoints containing long base64-encoded ci or cb parameter values that decode to PHP serialized data (strings beginning with O:, a:, or s:).
  • Web server access logs showing repeated comment submissions from the same authenticated member with unusually large ci or cb payloads.

Detection Strategies

  • Inspect POST bodies to the Comments plugin endpoints and flag base64 payloads whose decoded content matches PHP serialization signatures such as O:<n>:" (object markers).
  • Enable PHP application logging to capture calls to unserialize() and correlate with the authenticated user session.
  • Compare cot_cache write patterns against historical baselines to surface anomalous inserts from web request contexts.

Monitoring Recommendations

  • Alert on database write operations to cot_cache originating from comment-related PHP execution paths outside normal cache refresh cycles.
  • Monitor authentication events for members exercising comment write privileges shortly before anomalous database activity.
  • Track outbound network connections and file system writes initiated by the PHP process handling comment submissions.

How to Mitigate CVE-2026-71294

Immediate Actions Required

  • Restrict the Auth_members setting in plugins/comments/comments.setup.php from 'RW' to 'R' for untrusted user groups until a patched release is applied.
  • Audit installed Cotonti plugins and custom code for additional classes containing exploitable __destruct, __wakeup, or __toString methods.
  • Review the cot_cache table and application logs for unexpected inserts consistent with POP-chain exploitation.

Patch Information

No vendor patch identifier is listed in the CVE record at time of publication. Monitor the Cotonti GitHub repository for a fix that adds ['allowed_classes' => false] to the affected unserialize() calls in CreateAction.php, EditAction.php, and DeleteAction.php.

Workarounds

  • Apply a local patch to the Comments plugin that passes ['allowed_classes' => false] as the second argument to every unserialize() invocation in the plugin.
  • Replace serialization-based state passing with signed JSON tokens for the ci and cb parameters to remove the object-instantiation primitive entirely.
  • Deploy a web application firewall rule to block requests to comment create and edit endpoints containing base64-decoded bodies matching PHP object markers such as O:<digit>:".
bash
# Example hardening: enforce allowed_classes=false in the Comments plugin
# Edit plugins/comments/controllers/actions/CreateAction.php
# Replace: unserialize(base64_decode($ci))
# With:    unserialize(base64_decode($ci), ['allowed_classes' => false])

# Edit plugins/comments/controllers/actions/EditAction.php
# Replace: unserialize(base64_decode($this->comeback))
# With:    unserialize(base64_decode($this->comeback), ['allowed_classes' => false])

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.