SECURITYHIGHCVE-2026-14637

CVE-2026-14637: PHP Deserialization RCE in CodeIgniter Ecommerce Bootstrap Shopping Cart

A high-severity PHP deserialization vulnerability in the kirilkirkov Ecommerce-CodeIgniter-Bootstrap allows attackers to inject malicious serialized...

Dylan H.

Security Team

July 5, 2026
4 min read
CVE-2026-14637: PHP Deserialization RCE in CodeIgniter Ecommerce Bootstrap Shopping Cart

Affected Products

  • kirilkirkov/Ecommerce-CodeIgniter-Bootstrap (up to commit 13fd582aaf49)
  • ShoppingCart.php — getCartItems() library function
  • CodeIgniter-based PHP ecommerce applications

Executive Summary

CVE-2026-14637 is a high-severity PHP deserialization vulnerability in kirilkirkov/Ecommerce-CodeIgniter-Bootstrap. The getCartItems() function in application/libraries/ShoppingCart.php passes the shopping_cart cookie value directly to PHP's unserialize() without sanitization, enabling PHP Object Injection attacks that can escalate to full Remote Code Execution through a crafted gadget chain.

CVSS Score: 8.2 (High)

This class of vulnerability is particularly dangerous because exploitation requires no special privileges — any visitor with a browser can craft the malicious cookie and deliver it.


Vulnerability Overview

Root Cause

The getCartItems() function in the shopping cart library reads the shopping_cart cookie and deserializes it with no input validation:

// Vulnerable pattern (simplified)
public function getCartItems() {
    $cart_data = $this->input->cookie('shopping_cart');
    return unserialize($cart_data);  // DANGEROUS: user-controlled input
}

When PHP deserializes an attacker-supplied object, it automatically calls magic methods (__wakeup, __destruct, __toString) on the constructed object. If the application's codebase contains usable "gadget" classes — objects whose magic methods perform dangerous operations — the attacker can chain them to execute arbitrary commands.

Attack Surface

ComponentDetail
Entry Pointshopping_cart HTTP cookie
Auth RequiredNone — any unauthenticated visitor
MechanismPHP unserialize() on attacker-controlled data
ImpactRCE, file write, credential theft, denial of service
CVSS8.2 (High) — network accessible, no privileges required

Attack Chain

1. Attacker identifies target running vulnerable ecommerce framework
2. Scans codebase for usable PHP gadget chains (__destruct, __wakeup, etc.)
3. Crafts serialized PHP object payload encoding the gadget chain
4. Sends crafted payload as shopping_cart cookie in HTTP request
5. Server calls unserialize() — PHP constructs attacker's objects
6. Magic method fires, executes arbitrary OS command
7. Attacker achieves full remote code execution

Technical Details

PHP Object Injection Mechanics

PHP deserialization is fundamentally different from parsing JSON or XML — it reconstructs actual PHP objects, including calling their lifecycle hooks. An attacker who can control the input to unserialize() can:

  1. Instantiate any class available in the application's autoloader
  2. Trigger __wakeup() on deserialization
  3. Trigger __destruct() when the object goes out of scope
  4. Chain multiple objects via property references

Example Gadget Pattern (Generic)

class FileWriter {
    public $filename;
    public $content;
 
    public function __destruct() {
        // This fires automatically when object is destroyed
        file_put_contents($this->filename, $this->content);
    }
}
 
// Attacker serializes:
$exploit = new FileWriter();
$exploit->filename = '/var/www/html/shell.php';
$exploit->content = '<?php system($_GET["cmd"]); ?>';
echo serialize($exploit);
// Output: O:10:"FileWriter":2:{s:8:"filename";s:30:...}

PHPGGC — Automated Gadget Chain Generation

Tools like PHPGGC automate gadget chain discovery for popular PHP frameworks including CodeIgniter. An attacker can generate a working payload in seconds:

phpggc CodeIgniter/RCE1 system id

Affected Versions

CommitStatus
Up to 13fd582aaf49aeab7438acc0fc3eb973a1f5e6a7Vulnerable
No CVE-specific patch published at time of disclosureCheck upstream

Remediation

Fix: Replace unserialize() with json_decode()

The safest remediation is to stop using PHP serialization for cookie storage entirely:

// SECURE: Use JSON instead of PHP serialization
public function getCartItems() {
    $cart_data = $this->input->cookie('shopping_cart');
    // json_decode does not instantiate PHP objects
    return json_decode($cart_data, true) ?? [];
}
 
public function saveCartItems($items) {
    $this->input->set_cookie('shopping_cart', json_encode($items), 86400);
}

If PHP Serialization Must Be Retained

Use unserialize() with an explicit allowlist of permitted classes:

// Restrict deserialization to known-safe classes only
$allowed_classes = ['CartItem', 'ProductRef'];
$cart = unserialize($cart_data, ['allowed_classes' => $allowed_classes]);

Additional Hardening

  • Digitally sign cookie values (HMAC-SHA256) to prevent tampering
  • Store cart data server-side (session or database) — never trust client-side serialized state
  • Audit all unserialize() calls in the codebase for user-controlled input

Detection

Identify unserialize() Usage in Codebase

grep -rn "unserialize(" application/ --include="*.php"

Monitor for Deserialization Attack Patterns in Logs

# Look for serialized object patterns in cookie headers
grep -E 'shopping_cart=O:[0-9]' /var/log/apache2/access.log

WAF Rule (ModSecurity)

SecRule REQUEST_COOKIES:shopping_cart "@rx O:[0-9]+:\"" \
    "id:2026146370,phase:1,deny,status:400,\
    msg:'CVE-2026-14637 PHP Object Injection Attempt'"

References