CVE-2026-71294
CVE-2026-71294 — Cotonti CMS Comments Plugin PHP Object Injection
Executive Summary
CVE-2026-71294 is a PHP Object Injection vulnerability in the Cotonti CMS Comments plugin, arising from unsanitized unserialize() calls on user-supplied POST parameters. Any authenticated user with member-level write access to comments (the default Auth_members => 'RW' permission) can craft a malicious serialized PHP object that, when deserialized and subsequently garbage-collected, triggers a POP (Property-Oriented Programming) chain. The vulnerability has been demonstrated in practice using Cotonti's own MySQL_cache class, which allows an attacker to execute arbitrary database INSERT operations against the cot_cache table. The CVSS 3.1 score of 7.6 (High) reflects the high confidentiality impact, with the attack being remotely exploitable over the network with low attack complexity and low privilege requirements. Given the demonstrated POP-chain exploitation, the practical impact could extend to remote code execution depending on available gadget chains within a specific Cotonti installation.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Vulnerability Mechanism
The root cause is the unsafe use of PHP's unserialize() function without the allowed_classes parameter restriction. When unserialize() is invoked without restricting allowed classes, an attacker-controlled serialized payload can instantiate arbitrary classes loaded within the application's scope. This creates a PHP Object Injection primitive that can be leveraged through POP chains to achieve malicious outcomes.
The vulnerability exists in two (and potentially three) distinct code paths within the Comments plugin:
Sink 1 — CreateAction.php:
The file located at plugins/comments/controllers/actions/CreateAction.php retrieves a POST parameter named ci via the Cotonti framework function cot_import('ci', 'P', 'TXT'). The 'TXT' sanitization type applies only trim operations — it does not strip or neutralize serialized PHP data. The raw base64-encoded value is then passed to unserialize(base64_decode($ci)) with no allowed_classes restriction.
This code path is reachable by any member with write access to comments — the default setting for Auth_members in plugins/comments/comments.setup.php is 'RW', meaning standard registered members can post comments and thus reach this sink.
Sink 2 — EditAction.php:
The file at plugins/comments/controllers/actions/EditAction.php contains a method prepareComeBack() that processes a cb parameter. This parameter is similarly deserialized via unserialize(base64_decode($this->comeback)) without class restrictions. This path is reachable by any member editing their own comment.
Sink 3 — DeleteAction.php (partially mitigated):
A third sink exists in DeleteAction.php with an identical unserialize() pattern, but it is gated behind an admin-only authorization check, reducing its exploitability to administrative accounts only.
POP Chain Demonstration
The NVD description confirms a practical demonstration of the vulnerability using Cotonti's own MySQL_cache class. The attack chain operates as follows:
- The attacker crafts a serialized
MySQL_cacheobject containing attacker-chosen parameters. - The payload is base64-encoded and submitted to the vulnerable sink.
- The object is deserialized and stored in memory; no immediate action occurs at deserialization time.
- During PHP garbage collection, the
__destruct()method of theMySQL_cacheobject executes, invoking aflush()method. - The
flush()chain results in an attacker-controlledINSERT INTO cot_cachestatement with attacker-chosen row values, confirming genuine POP-chain exploitation and arbitrary database modification.
The NVD description explicitly notes that further impact (including potential RCE) is contingent on other gadget chains available within a given Cotonti installation's loaded classes. This means the severity could vary depending on which additional classes are available in the application's runtime class scope.
Attack Surface
- Authentication required: Yes — member-level account (low privilege)
- Network accessibility: Yes — HTTP POST requests to comment creation/edit endpoints
- Attack complexity: Low — no special conditions or race conditions required
- User interaction: None required
Exploitation Scenarios
Attack Chain: PHP Object Injection → Database Manipulation → Potential RCE
Stage 1 — Reconnaissance and Target Identification
The attacker first identifies a Cotonti CMS instance by fingerprinting the application via HTTP response headers, meta tags, or distinctive URL patterns typical of Cotonti installations. The attacker then registers a standard member account (or compromises an existing one) to obtain the minimum RW write access to comments. Alternatively, the attacker may already possess valid credentials through credential stuffing or prior phishing.
Stage 2 — Payload Construction and Weaponization
The attacker enumerates available classes within the target Cotonti installation by reviewing public source code repositories and Cotonti's standard class hierarchy. The attack payload is constructed as follows:
$payload = new MySQL_cache(/* attacker-controlled parameters */);
$serialized = base64_encode(serialize($payload));
For the CreateAction sink, the attacker prepares a POST request to the comment-creation endpoint with the ci parameter set to the crafted base64-encoded payload. Since the cot_import('ci', 'P', 'TXT') only trims whitespace, the encoded payload passes through unchanged.
For the EditAction sink, the attacker edits an existing comment and supplies the malicious cb parameter in the request, which the prepareComeBack() method processes.
Stage 3 — Payload Delivery and Trigger
POST /index.php?r=comments/actions/create HTTP/1.1
Host: target-cotonti-site.com
Cookie: [session cookie for authenticated member]
ci=<base64-encoded serialized MySQL_cache object>
The server-side code calls unserialize(base64_decode($ci)), instantiating the MySQL_cache object in the application's memory space. At this point, no visible effect occurs — the object is idle until garbage collection.
Stage 4 — Trigger and Post-Exploitation Impact
When PHP's garbage collector destroys the MySQL_cache object (either at script termination or when the object goes out of scope), the __destruct() magic method executes. This triggers the flush() chain, resulting in:
Database compromise: An attacker-controlled
INSERT INTO cot_cachestatement executes, modifying thecot_cachetable with arbitrary row values. This could allow:- Poisoning cached data to cause further application misbehavior
- Writing persistent data that influences downstream authenticated or administrative actions
- Defacing cache-driven content rendered to other users (high confidentiality/integrity impact)
Escalation potential (installation-dependent): If additional gadget classes exist within the Cotonti installation (such as classes that invoke filesystem operations, eval, or command execution), the attacker can chain them for remote code execution. The NVD description explicitly acknowledges this possibility as "contingent on other gadget chains."
Stage 5 — Persistence and Lateral Movement
The attacker can iterate across multiple comment threads, repeatedly delivering payloads to maintain a persistent presence in the cot_cache table. Since the vulnerability is unpatched, each delivery yields the same exploit result. The database manipulation capacity could be leveraged to modify application state, inject administrative sessions, or alter configuration data stored in the database.
Impact Assessment
CVSS Analysis: The CVSS 3.1 score of 7.6 (High) breaks down as:
- Attack Vector: Network (AV:N) — Exploitable over HTTP
- Attack Complexity: Low (AC:L) — No special conditions required
- Privileges Required: Low (PR:L) — Only member-level access needed
- User Interaction: None (UI:N) — No victim interaction required
- Impact: High Confidentiality (C:H), Low Integrity (I:L), Low Availability (A:L)
Business Impact:
- Data confidentiality: The demonstrated POP chain allows arbitrary database modification, which can expose cache contents that may contain sensitive user data, session tokens, or privileged information.
- Data integrity: Attacker-controlled INSERT statements into
cot_cachecan corrupt application state, deface content, or inject malicious data that propagates through the application. - Availability: Malformed cache entries could cause application errors or degrade performance, affecting site availability for all users.
- Reputation: A successful exploit on a public Cotonti deployment undermines the security posture of the operating organization.
Blast Radius:
- Comment functionality: The primary affected component — all users who can post or edit comments are potential attackers.
- Database layer: The
cot_cachetable is the demonstrated target, but other database objects may be reachable depending on available gadget chains. - Underlying server: If RCE is achieved through alternative gadget chains, the blast radius extends to the entire web server environment — the underlying OS, co-hosted applications, and the local network.
Affected Systems: All Cotonti CMS installations running the Comments plugin with default permissions are vulnerable. The Auth_members => 'RW' default means that virtually any registered user can trigger the vulnerability.
Detection Guidance
Sigma Rule
title: Cotonti CMS Comments Plugin PHP Object Injection Attempt
id: 9a4e8b7c-3f21-4a5b-8c7d-6e5f4a3b2c1d
status: experimental
description: Detects base64-encoded serialized PHP objects in Cotonti comment POST parameters (ci or cb)
author: Valtersit Threat Intelligence
date: 2026/06/10
tags:
- attack.t1190
- attack.initial-access
- cve.2026.71294
- cwe.502
logsource:
category: webserver
product: apache
definition: 'Apache access logs with POST body logging or WAF logs inspecting request parameters'
detection:
selection_create:
cs-method: 'POST'
c-uri|contains: 'comments'
cs-uri-query|contains: 'create'
selection_edit:
cs-method: 'POST'
c-uri|contains: 'comments'
cs-uri-query|contains: 'edit'
selection_payload_pattern:
# Base64-decoded serialized PHP object signature: O:<digit>:"<classname>"
request_body|contains|all:
- 'ci='
- 'Tzpc'
# Alternate pattern for cb parameter: base64 of 'O:' is 'Tzo='
condition: (selection_create or selection_edit) and request_body|contains|all:
- 'Tzo'
- 'Y291bnRl'
falsepositives:
- Legitimate uploads of serialized data (unlikely in comment context)
level: high
YARA Rule
rule CVE_2026_71294_Cotonti_PHP_Object_Injection
{
meta:
author = "Valtersit Threat Intelligence"
description = "Detects base64-encoded serialized PHP objects targeting Cotonti Comments plugin"
cve = "CVE-2026-71294"
date = "2026-06-10"
severity = "high"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-71294"
strings:
// Base64 encoding of 'O:' (opening of serialized PHP object declaration)
$b64_object_prefix = "Tzo"
// Base64 encoding of 'O:1:' (short class names)
$b64_short_class = "Tzox"
// Base64 encoding of 'O:10:' (common class name length)
$b64_class_len = "TzoxMA"
// Base64 encoding of 'MySQL_cache' class name
$b64_mysql_cache = "TXlTUUxfY2FjaGU"
// Base64 encoding of 'cot_cache' table reference
$b64_cot_cache = "Y290X2NhY2hl"
// URL-encoded base64 variants (plus signs replaced)
$url_encoded_prefix = "Tzo"
// Raw serialized pattern references
$serialized_obj = "s:"
$destruct_method = "__destruct"
$flush_method = "flush"
condition:
(uint16(0) == 0x4D5A or filesize > 0) and
(any of ($b64_*) and any of ($b64_mysql_cache*, $b64_cot_cache*)) and
1 of ($serialized_obj*)
}
Suricata IDS Rule
alert http any any -> $HOME_NET any (msg:"CVE-2026-71294 - Cotonti Comments Plugin PHP Object Injection via ci parameter"; flow:established,to_server; http.method; content:"POST"; http.uri; content:"comments"; http.uri; content:"create"; http.request_body; pcre:"/ci\s*=\s*Tzo[0-9A-Za-z+\/=\-_]+/i"; classtype:attempted-admin; reference:cve,2026-71294; reference:url,https://nvd.nist.gov/vuln/detail/CVE-2026-71294; sid:10071294; rev:1;)
alert http any any -> $HOME_NET any (msg:"CVE-2026-71294 - Cotonti Comments Plugin PHP Object Injection via cb parameter"; flow:established,to_server; http.method; content:"POST"; http.uri; content:"comments"; http.uri; content:"edit"; http.request_body; pcre:"/cb\s*=\s*Tzo[0-9A-Za-z+\/=\-_]+/i"; classtype:attempted-admin; reference:cve,2026-71294; reference:url,https://nvd.nist.gov/vuln/detail/CVE-2026-71294; sid:10071295; rev:1;)
alert http any any -> $HOME_NET any (msg:"CVE-2026-71294 - Cotonti Potential MySQL_cache serialized object in request body"; flow:established,to_server; http.request_body; content:"TXlTUUxfY2FjaGU"; classtype:attempted-admin; reference:cve,2026-71294; reference:url,https://nvd.nist.gov/vuln/detail/CVE-2026-71294; sid:10071296; rev:1;)
Elastic Detection
// EQL Query for detecting Cotonti PHP Object Injection attempts
// Designed for Elastic Security — execute on HTTP/web server event category
sequence by host.name, source.ip
[ network where event.category == "network" and
network.protocol == "http" and
source.ip != null and
destination.port in (80, 443) ]
[ http where event.category == "http" and
http.request.method == "POST" and
url.path like~ "*comments*" and
(url.path like~ "*create*" or url.path like~ "*edit*") and
request.body.content != null and
(
// Base64-encoded serialized PHP object prefix "O:" → "Tzo"
request.body.content like~ "*Tzo*" or
// URL-safe or standard base64 of "O:"
request.body.content like~ "*Tzo%3D*" or
// MySQL_cache class name in base64
request.body.content like~ "*TXlTUUxfY2FjaGU*"
) ]
Splunk SPL Query
index=web sourcetype=access_combined OR sourcetype=apache_access
| where method="POST"
AND (uri_path LIKE "%comments%create%" OR uri_path LIKE "%comments%edit%")
AND (
form_data LIKE "%ci=%Tzo%"
OR form_data LIKE "%cb=%Tzo%"
OR form_data LIKE "%ci=*Tzo*"
OR form_data LIKE "%cb=*Tzo*"
OR form_data LIKE "%TXlTUUxfY2FjaGU%"
)
| eval vulnerability=CVE-2026-71294
| eval indicator="PHP Object Injection - base64 serialized payload"
| table _time, src_ip, user, uri_path, http_user_agent, form_data
| sort -_time
| stats count by src_ip, user, uri_path
| where count > 1
Wazuh OSSEC Rule
<group name="web, cve_2026_71294,">
<rule id="100294" level="12">
<decoded_as>web</decoded_as>
<description>CVE-2026-71294: Cotonti Comments Plugin PHP Object Injection via ci parameter</description>
<field name="method">POST</field>
<field name="url">\.*comments.*create.*</field>
<regex>ci\s*=\s*Tzo</regex>
<group>cve_2026_71294,pci_dss_6.5.5,gdpr_32,</group>
<mitre>
<id>T1190</id>
</mitre>
<info type="cve">CVE-2026-71294</info>
<options>no_full_log</options>
<alert_email>soc@example.com</alert_email>
</rule>
<rule id="100295" level="12">
<decoded_as>web</decoded_as>
<description>CVE-2026-71294: Cotonti Comments Plugin PHP Object Injection via cb parameter</description>
<field name="method">POST</field>
<field name="url">\.*comments.*edit.*</field>
<regex>cb\s*=\s*Tzo</regex>
<group>cve_2026_71294,pci_dss_6.5.5,gdpr_32,</group>
<mitre>
<id>T1190</id>
</mitre>
<info type="cve">CVE-2026-71294</info>
<options>no_full_log</options>
<alert_email>soc@example.com</alert_email>
</rule>
<rule id="100296" level="14">
<decoded_as>web</decoded_as>
<description>CVE-2026-71294: Cotonti Comments Plugin - MySQL_cache class detected in POST body (potential exploit)</description>
<field name="method">POST</field>
<field name="url">\.*comments.*</field>
<regex>TXlTUUxfY2FjaGU</regex>
<group>cve_2026_71294,pci_dss_6.5.5,gdpr_32,</group>
<mitre>
<id>T1190</id>
</mitre>
<info type="cve">CVE-2026-71294</info>
<options>no_full_log</options>
<alert_email>soc@example.com</alert_email>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 0/4 — UNPATCHED. No patch evidence from any tracked source. Vendor fix is not available. Affected version list is empty — all versions are presumed affected.
1) Immediate Mitigations (Defense in Depth)
When no vendor patch exists, the following compensating controls should be implemented immediately:
- Restrict member write access: Change the
Auth_memberssetting inplugins/comments/comments.setup.phpfrom'RW'to'R'(read-only) or denylist member comment creation/modification entirely. This blocks the low-privilege attack path but may break core functionality. - Web Application Firewall (WAF) rules: Deploy the Suricata rules above at the network edge or equivalent WAF signatures (ModSecurity CRS, AWS WAF, Cloudflare) to block POST requests containing base64-encoded serialized PHP object signatures (
Tzoprefix patterns) in comment submission endpoints. - PHP configuration hardening: Although the application must be patched for full remediation, consider running Cotonti with
suhosinextensions enabled (if available for the PHP version) or applying PHP-level allowlisted class auto-loading filters. - Input validation middleware: Implement a reverse-proxy or framework-level filter that rejects POST parameters named
ciorcbcontaining base64-encoded serialized PHP structures. - Database access control: Restrict the database user account used by the Cotonti application to least-privilege (no CREATE/ALTER/DROP privileges, only INSERT/UPDATE/DELETE/SELECT on necessary tables).
2) Patch/Upgrade Steps
- Monitor for vendor release: Subscribe to Cotonti CMS security advisories and the TuranSec security mailing list. When a patched version is released, upgrade immediately.
- Apply the upstream fix once available: The fix will ultimately be to replace
unserialize()calls with:
or implement strict class allowlisting specific to the data structure expected (in this case, likely no object instantiation is needed — the parameters should be plain scalar values).$data = unserialize($input, ['allowed_classes' => false]); - Version pinning: Once a patched version is available, pin your deployment to the fixed version and test thoroughly before production rollout.
3) Long-Term Hardening
- Code audit: Review all
unserialize()calls across your Cotonti installation and replace them withjson_decode()orunserialize(..., ['allowed_classes' => false])where object instantiation is unnecessary. - PHP version hygiene: Keep PHP updated to the latest supported minor version to benefit from language-level security hardening.
- Class loading restriction: If a full patch is unavailable, implement an autoloader wrapper that blocks instantiation of sensitive classes (e.g.,
MySQL_cache, filesystem, eval-related classes) when they originate from deserialization contexts. - Application security testing: Integrate automated SAST/DAST tools into your CI/CD pipeline to catch unsafe
unserialize()patterns in future code. - Continuous monitoring: Keep the detection rules in this report active in your SIEM/WAF stack, as exploitation of unpatched instances is expected to continue.
References
- NVD Advisory: https://nvd.nist.gov/vuln/detail/CVE-2026-71294 — Official CVE record with NVD description, CVSS v3.1 scoring, and CWE mapping.
- CWE-502 Reference: https://cwe.mitre.org/data/definitions/502.html — Deserialization of Untrusted Data weakness description and associated guidance.
- OWASP Deserialization Cheat Sheet: https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html — Industry guidance for mitigating unsafe deserialization, applicable to this vulnerability class.
- Cotonti CMS Official Site: https://www.cotonti.com/ — For monitoring official releases and security announcements from the project maintainers.
- CISA Known Exploited Vulnerabilities Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog — This CVE is NOT listed in the CISA KEV catalog as of the report date; however, it is recommended to re-check periodically for updates.
Threat Actor Activity: No known threat actor campaigns have been publicly attributed to exploitation of this CVE at the time of this report. The EPSS probability score of 0.00224 (13.1st percentile) indicates a low current exploitation probability in the wild; however, the availability of a practical POP-chain demonstration in the NVD description increases the risk of future weaponization. Organizations running Cotonti CMS should treat this vulnerability as high-risk and implement mitigations proactively.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.