CVE-2022-21647 Overview
CVE-2022-21647 is an insecure deserialization vulnerability discovered in CodeIgniter4, an open source PHP full-stack web framework. The vulnerability exists in the old() function, which unsafely deserializes user-controlled data. Remote attackers can exploit this flaw to inject auto-loadable arbitrary objects, potentially leading to arbitrary PHP code execution on the server. A working exploit has been confirmed that can lead to SQL injection attacks.
Critical Impact
Remote attackers can exploit insecure deserialization in CodeIgniter4's old() function to execute arbitrary PHP code and perform SQL injection attacks without authentication.
Affected Products
- CodeIgniter4 versions prior to v4.1.6
- Applications using the old() function and form_helper
- Applications using RedirectResponse::withInput() and redirect()->withInput()
Discovery Timeline
- 2022-01-04 - CVE-2022-21647 published to NVD
- 2024-11-21 - Last updated in NVD database
Technical Details for CVE-2022-21647
Vulnerability Analysis
The vulnerability stems from unsafe deserialization within CodeIgniter4's old() function. This function is commonly used in forms to repopulate input fields with previously submitted data after validation failures. The core issue is that the function directly calls PHP's unserialize() on user-controlled input without proper validation.
When the old() function retrieves previously submitted form data, it checks if the stored value is a serialized array or string by examining the prefix (a: for arrays or s: for strings). If the condition matches, it blindly deserializes the data. This allows attackers to craft malicious serialized payloads that, when deserialized, can instantiate arbitrary PHP objects with attacker-controlled properties.
The vulnerability is classified as CWE-502 (Deserialization of Untrusted Data). Successful exploitation can lead to remote code execution through PHP object injection, and a confirmed exploit path demonstrates the ability to perform SQL injection attacks on vulnerable systems.
Root Cause
The root cause is the direct use of PHP's unserialize() function on untrusted user input within the old() helper function. The vulnerable code path checked if the value started with a: (serialized array) or s: (serialized string) and proceeded to deserialize it without any integrity verification or input sanitization. This design allows attackers to inject malicious serialized objects that trigger dangerous operations when instantiated through PHP's magic methods like __wakeup(), __destruct(), or __toString().
Attack Vector
The attack vector is network-based and requires no authentication or user interaction. An attacker can exploit this vulnerability by:
- Submitting malicious serialized PHP objects through form inputs that will be stored and later processed by the old() function
- Crafting payloads that exploit available gadget chains within the application or its dependencies
- When the old() function processes the malicious input, the unserialize() call instantiates the attacker's objects, triggering code execution
The vulnerable code that was removed in the patch:
// Vulnerable code removed in the security patch
// If the result was serialized array or string, then unserialize it for use...
if (is_string($value) && (strpos($value, 'a:') === 0 || strpos($value, 's:') === 0)) {
$value = unserialize($value);
}
Source: GitHub Commit Record
The patch in system/Common.php removes the unsafe deserialization logic entirely:
return $default;
}
- // If the result was serialized array or string, then unserialize it for use...
- if (is_string($value) && (strpos($value, 'a:') === 0 || strpos($value, 's:') === 0)) {
- $value = unserialize($value);
- }
-
return $escape === false ? $value : esc($value, $escape);
}
}
Source: GitHub Commit Record
Detection Methods for CVE-2022-21647
Indicators of Compromise
- Unusual serialized PHP objects appearing in form submissions or session data (patterns starting with O: for objects, a: for arrays)
- Unexpected database queries or SQL errors following form submissions
- Error logs showing PHP object instantiation failures or unexpected class loading
- Web application firewall alerts for serialized data patterns in HTTP requests
Detection Strategies
- Monitor HTTP request bodies for serialized PHP data patterns (e.g., O:[0-9]+:, a:[0-9]+:, s:[0-9]+:)
- Implement application logging to track calls to the old() function and analyze input patterns
- Deploy SentinelOne's Application Control to detect unusual PHP process behaviors and unexpected code execution
- Use static code analysis tools to identify usage of vulnerable CodeIgniter4 versions and the affected functions
Monitoring Recommendations
- Enable detailed web server access logs and monitor for anomalous POST requests containing serialized data
- Configure SIEM rules to alert on PHP deserialization attack signatures
- Monitor application performance metrics for unusual CPU or memory spikes that may indicate successful exploitation
- Review database query logs for unauthorized or malformed queries originating from web application processes
How to Mitigate CVE-2022-21647
Immediate Actions Required
- Upgrade CodeIgniter4 to version 4.1.6 or later immediately
- If immediate upgrade is not possible, avoid using the old() function, form_helper, RedirectResponse::withInput(), and redirect()->withInput() methods
- Review application code for any custom deserialization logic and ensure proper input validation
- Audit access logs for evidence of exploitation attempts
Patch Information
The CodeIgniter team has addressed this vulnerability in version 4.1.6. The fix removes the unsafe unserialize() call entirely from the old() function in system/Common.php. Users should upgrade to this version or later as the recommended remediation.
For detailed patch information, refer to the GitHub Commit Record and the GitHub Security Advisory.
Workarounds
- Disable or remove usage of the old() function from all form templates until patching is complete
- Do not use redirect()->withInput() or RedirectResponse::withInput() methods
- Implement a Web Application Firewall (WAF) rule to block requests containing serialized PHP data patterns
- Consider implementing a custom wrapper around form handling that validates input types before processing
# Upgrade CodeIgniter4 using Composer
composer require codeigniter4/framework:^4.1.6
# Verify the installed version
composer show codeigniter4/framework | grep versions
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


