
Insecure Deserialization in e107 CMS install.php
Reported: September 18, 2025
CVE Assigned: October 9, 2025
Published: February 02, 2026
CVE ID: CVE-2025-61505
Discoverer: Anas Abderrahman Benbarek
A PHP Object Injection vulnerability (CWE-502: Deserialization of Untrusted Data) was discovered in the installation script (install.php) of e107 CMS version 2.3.3.
The vulnerability allows unauthenticated remote attackers to craft malicious serialized data, potentially leading to arbitrary code execution, data manipulation, or other malicious actions — depending on the presence of exploitable gadget classes in the e107 codebase or its dependencies.
This issue stems from the unsafe use of PHP's unserialize() function on user-controlled input without any restrictions (such as the allowed_classes option). While limited to the installation phase, it poses a significant risk during setup on exposed servers, as the installer handles sensitive operations like database creation and file writing.
install.php)The e107 CMS installation process is multi-stage. User inputs (language, database credentials, admin details, etc.) are persisted across steps using a serialized array stored in the previous_steps POST parameter. This data is base64-encoded for transmission and decoded/unserialized on the server.
The core issue is the direct passing of decoded user input to unserialize() without validation, sanitization, or class whitelisting. This happens in two places:
php if(isset($_POST['previous_steps'])) { $tmp = unserialize(base64_decode($_POST['previous_steps'])); $override = (isset($tmp['paths']) && isset($tmp['paths']['hash'])) ? array('site_path'=>$tmp['paths']['hash']) : array(); unset($tmp); }
The script assumes previous_steps contains trusted serialized data from previous form steps. But since it's a plain POST parameter, an attacker controls it completely. base64_decode() turns the input into binary, and unserialize() reconstructs it into PHP objects or arrays. If the input contains object notation (starting with O:), PHP instantiates those classes if they exist in the current scope or are autoloaded. This can immediately trigger __wakeup() or other magic methods, potentially causing side effects like file writes or unexpected database calls if gadget chains are present. Exploitability Note: Success depends on available gadget classes. Without them, impact may be limited to crashes or data corruption.
PHPif(isset($_POST['previous_steps'])) { $this->previous_steps = unserialize(base64_decode($_POST['previous_steps'])); // ... (filtering and password restoration logic) unset($_POST['previous_steps']); }
This instance is more dangerous because the deserialized data becomes part of the object state ($this->previous_steps) and influences later installer actions (MySQL setup, admin creation, config file generation). Object injection here can persist across the install process and affect high-privilege operations. Again, no allowed_classes restriction means any autoloaded class (core, handlers, plugins, libraries) can be instantiated. Exploitability Note: Real-world exploitation typically requires chaining multiple objects (a "gadget chain") to reach dangerous behavior like code execution. For example, one class's __wakeup() could call another method that evaluates user-controlled strings. Without such chains, the impact might stay at denial-of-service (e.g., resource exhaustion in destructors). The installer's high-privilege context (writing e107_config.php, creating directories) amplifies risks, but removing the script post-install reduces long-term exposure. The vulnerability is reachable via unauthenticated HTTP POST requests to /install.php during any setup stage.
Remove install.php — Delete or rename the script immediately after installation. Restrict access — Use .htaccess, nginx rules, or move the file outside the web root during deployment. Patch recommendation — Replace unserialize() with json_decode() for state persistence, or at minimum use:
unserialize($data, ['allowed_classes' => false]);
Add HMAC signing/validation of the data for extra integrity.
e107 CMS Official Website: https://e107.org e107 CMS GitHub Repository: https://github.com/e107inc/e107 CVE Record: CVE-2025-61505 (will be updated once published) CWE-502: Deserialization of Untrusted Data: https://cwe.mitre.org/data/definitions/502.html