☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
[ VENDOR STATS ]
CVSS: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N 🐛 CWE-89
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-15941

CVE-2026-15941 SQL Injection in Relevanssi
📅 PUBLISHED: 2026-08-05 00:00 UTC 🔄 UPDATED: 2026-09-23 20:26 UTC
[ PATCH UNDER REVIEW ↓ ] Remains UNDER REVIEW until an independent source confirms the fix
[ DEFENSE PATCH ↓ ]
💣 PoC: Public
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.24%
👁️
0.24% probability
6.0× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
🥷 MITRE: T1190
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
VULNERABLE: version not auto-detected — verify your deployed version locally
CVSS VECTOR BREAKDOWN 6.5
AV: N Attack Vector Network
AC: L Attack Complexity Low
PR: L Privileges Required Low
UI: N User Interaction None
S: U Scope Unchanged
C: H Confidentiality High
I: N Integrity None
A: N Availability None
6.5
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-15941 is a time-based blind SQL injection vulnerability in the Relevanssi WordPress search plugin's Admin Search AJAX handler. An authenticated attacker with only edit_posts capability (contributor-level) can inject arbitrary SQL through a URL-encoded args parameter, leading to full database exfiltration without requiring any special privileges. The vulnerability carries a CVSS score of 6.5 (Medium severity), reflecting the low complexity and network exploitability, though the impact is limited to the database's confidentiality. At the time of this report, no official vendor patch exists, and the plugin remains exposed in active WordPress installations.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

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.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Technical Analysis

The vulnerability resides in the Relevanssi plugin's Admin Search functionality, which is exposed via an AJAX endpoint accessible from the WordPress dashboard. The plugin authenticates users based on the edit_posts capability, meaning any user with this permission—including subscriber-level accounts that have been granted posting rights—can access the affected handler.

Vulnerability Mechanism:

  1. Parameter Handling: The AJAX handler receives a POST request containing a URL-encoded args parameter. This parameter is expected to contain serialized query arguments that will be parsed into a WP_Query object.

  2. Parsing Logic: The plugin calls parse_str() or similar PHP functions to decode the args parameter, then constructs a WP_Query instance with the resulting array. This array can include arbitrary WordPress query variables, including tax_query parameters.

  3. Taxonomy Restriction Builder: When a tax_query is present, Relevanssi passes the taxonomy data to its internal taxonomy restriction builder. This component is responsible for generating SQL fragments that restrict search results based on taxonomy terms.

  4. SQL Injection Point: The taxonomy value is sanitized using WordPress's sanitize_text_field() function, which strips HTML tags and line breaks. However, this sanitization does not parameterize the value for SQL. The plugin then interpolates the sanitized value directly into a SQL query string that queries the wp_term_taxonomy table:

SELECT term_taxonomy_id FROM wp_term_taxonomy 
WHERE term_id = 'VALUE_HERE' AND taxonomy = 'VALUE_HERE'

Since both values are concatenated into the query without using $wpdb->prepare() with proper placeholders, an attacker can inject SQL by crafting values that break out of the single-quoted string context.

  1. Blind Exploitation: The query is wrapped in a conditional that affects response timing. By injecting a SLEEP() function or a heavy subquery, the attacker can measure response delays to infer whether their injected conditions are true, enabling time-based blind extraction of database contents.

Attack Surface Details:

  • Endpoint: WordPress admin-ajax.php (action hook specific to Relevanssi)
  • Authentication Required: Yes — edit_posts capability only
  • Network Vector: Remote, HTTP POST
  • SQL Database: MySQL/MariaDB (standard WordPress installations)
  • Interpolated Query: wp_term_taxonomy table, where the attacker controls both the term_id and taxonomy values

Exploitation Scenarios

The following attack chain demonstrates a concrete exploitation path for CVE-2026-15941:

Step 1 — Reconnaissance and Target Identification

The attacker enumerates WordPress sites running the Relevanssi plugin. Using Shodan dorks like http.component:"WordPress" http.body:"relevanssi" or by fingerprinting Relevanssi's distinctive HTML comments and script handles in page source, the attacker narrows the target pool. Alternatively, the attacker probes a known WordPress site for the plugin by checking for the Relevanssi admin scripts in /wp-admin/load-scripts.php or querying the plugin's data via REST API endpoints.

Step 2 — Attacker Privilege Establishment

The attacker requires a WordPress account with edit_posts capability. Common acquisition vectors include:

  • Registering a contributor account if the site allows open registration
  • Compromising an existing low-privilege account through credential stuffing or phishing
  • Purchasing access from initial-access brokers

A contributor account suffices—no admin or editor privileges are needed.

Step 3 — Crafting the Malicious Request

The attacker constructs an AJAX POST request to the vulnerable endpoint. The args parameter contains a serialized WordPress query array with a tax_query sub-array designed to inject SQL.

A crafted payload targeting the args parameter might look like:

args=tax_query[0][taxonomy]=term&tax_query[0][terms]=1') OR (SELECT(IF(MID((SELECT user_pass FROM wp_users LIMIT 1),1,1)='$',SLEEP(5),false)))-- -

The server-side logic decodes this as:

tax_query[0][taxonomy] = "term"
tax_query[0][terms] = "1') OR (SELECT(IF(MID((SELECT user_pass FROM wp_users LIMIT 1),1,1)='$',SLEEP(5),false)))-- -"

After sanitization (which removes HTML tags but preserves SQL metacharacters), the term_id value becomes:

1') OR (SELECT(IF(MID((SELECT user_pass FROM wp_users LIMIT 1),1,1)='$',SLEEP(5),false)))-- -

Step 4 — SQL Query Construction and Execution

The plugin builds the following vulnerable query:

SELECT term_taxonomy_id FROM wp_term_taxonomy 
WHERE term_id = '1') OR (SELECT(IF(MID((SELECT user_pass FROM wp_users LIMIT 1),1,1)='$',SLEEP(5),false)))-- -' 
AND taxonomy = 'term'

The injected )-- - terminates the WHERE clause and comments out the rest. The OR (SELECT(...SLEEP(5)...)) clause evaluates to true if the first character of the first user's password hash is $ (a valid prefix for phpass-hashed passwords), causing a 5-second delay in the response. Otherwise, the query returns instantly.

Step 5 — Time-Based Blind Data Extraction

The attacker iterates through characters and positions:

  • MID((SELECT user_pass FROM wp_users LIMIT 1),1,1) → guesses character at position 1
  • MID((SELECT user_pass FROM wp_users LIMIT 1),2,1) → for position 2 of the hash
  • Same pattern applied to user_login, user_email, and other table columns

Each request retrieves one character, and a standard brute-force over an alphanumeric-plus-symbol charset extracts a full password hash in approximately 62 requests per character position. Timing analysis distinguishes a successful guess (5-second delay) from an unsuccessful one (immediate response).

Step 6 — Post-Exploitation Escalation

Once the attacker has the admin password hash, they attempt offline cracking using John the Ripper or Hashcat against popular password lists. Because WordPress uses phpass (iterated MD5 with salted keys), weak admin passwords often crack quickly. Success grants full administrative access: site defacement, backdoor plugin installation, server-side code execution via theme/plugin file editing, and lateral movement to the hosting server.


Impact Assessment

Business Impact:

  • Confidentiality (C:H): Full database disclosure, including user credentials (password hashes), emails, session tokens, and any custom tables storing sensitive business data. For e-commerce sites, payment transaction metadata may be exposed.
  • Integrity (I:N): The vulnerability does not directly allow modification, but the resulting admin compromise enables full site takeover.
  • Availability (A:N): No direct denial of service; however, the SLEEP-based payloads can be used to exhaust database connections in a distributed attack.

Affected Systems:

  • Any WordPress installation running Relevanssi versions prior to a patch (currently all versions, as unpatched)
  • Particularly affected: multisite networks, WooCommerce stores, membership platforms, and content-heavy sites with active user bases

Blast Radius:

  • WordPress is deployed on ~43% of all websites; Relevanssi has over 700,000 active installations
  • The edit_posts requirement lowers the exploitation barrier—any user with contributor role is sufficient
  • No compatibility constraints: the vulnerability is OS-agnostic and database-agnostic (MySQL-compatible databases only)

CVSS Reference:

The CVSS:3.1 vector AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N scores 6.5. The scope is unchanged (S:U), confirming the database and the WordPress core share the same trust boundary. A legitimate concern: the Medium severity underplays real-world impact because time-based blind injection combined with modern GPU hash cracking yields near-certain admin credential compromise for weakly-padded sites.


Detection Guidance

Sigma Rule

title: Relevanssi Admin Search SQL Injection Attempt
id: c0f1e2a3-b4c5-4d6e-8f90-123456789abc
status: experimental
description: Detects SQL injection patterns in Relevanssi admin search AJAX requests
author: Valtersit Threat Intelligence
date: 2026/01/15
tags:
    - attack.t1190
    - attack.initial-access
logsource:
    category: webserver
    product: apache
detection:
    selection:
        cs-method: POST
        cs-uri-query|contains:
            - 'admin-ajax.php'
        cs-uri-query|contains|all:
            - 'action=relevanssi'
        request_body|contains:
            - "' OR (SELECT"
            - 'SLEEP('
            - "')-- -"
            - 'BENCHMARK('
            - "') UNION SELECT"
            - "') AND ("
    condition: selection
fields:
    - clientip
    - request_body
falsepositives:
    - Legitimate security scanner traffic
    - Misconfigured plugin queries with bracket syntax
level: high

YARA Rule

rule Relevanssi_SQLi_CVE_2026_15941
{
    meta:
        author = "Valtersit Threat Intelligence"
        description = "Detects SQL injection patterns targeting Relevanssi Admin Search"
        cve = "CVE-2026-15941"
        date = "2026-01-15"
        severity = "high"
    strings:
        $ajx = "admin-ajax.php" ascii wide nocase
        $act = "relevanssi" ascii wide nocase
        $sqli1 = "') OR (SELECT" ascii wide nocase
        $sqli2 = "SLEEP(" ascii wide nocase
        $sqli3 = "BENCHMARK(" ascii wide nocase
        $sqli4 = "' UNION SELECT" ascii wide nocase
        $sqli5 = ")-- -" ascii wide nocase
        $arg = "args=" ascii wide
        $tq_tax = "tax_query" ascii wide nocase
    condition:
        $ajx and $act and $arg and $tq_tax and 1 of ($sqli*)
}

Suricata IDS Rule

alert http any any -> any any (msg:"CVE-2026-15941 Relevanssi Admin Search SQL Injection Attempt"; flow:established,to_server; content:"POST"; http_method; content:"admin-ajax.php"; http_uri; content:"action=relevanssi"; http_uri; content:"args="; http_client_body; pcre:"/(?:'|\")\s*\)?\s*OR\s+\(?\s*SELECT/i"; pcre:"/SLEEP\s*\(\s*\d+\s*\)/i"; classtype:web-application-attack; reference:cve,2026-15941; sid:202615941; rev:1;)

Elastic Detection

sequence by source.ip with maxspan=30s
  [ network where network.protocol == "http" and
    http.request.method == "POST" and
    http.request.uri contains "admin-ajax.php" and
    http.request.body.content contains "action=relevanssi" and
    http.request.body.content contains "args=" and
    http.request.body.content contains "tax_query" ]
  [ network where network.protocol == "http" and
    http.response.bytes > 0 and
    (http.response.body.content contains "error" or
     http.response.body.content contains "failure") ]

Splunk SPL Query

index=web sourcetype=access_combined
| where match(_raw, "admin-ajax") AND match(_raw, "relevanssi") AND match(_raw, "args=")
| rex field=_raw "^(?<clientip>\S+)"
| rex field=_raw "POST (?<uri>[^ ]+)"
| search uri="*admin-ajax.php*"
| rex field=_raw "(?<body>args=[^&]+)"
| eval body=urldecode(body)
| where match(body, "(?i)(\'|\")?\s*OR\s+\(?\s*(SELECT|IF)") 
     OR match(body, "(?i)SLEEP\s*\(")
     OR match(body, "(?i)BENCHMARK\s*\(")
| table _time clientip uri body
| sort - _time

Wazuh OSSEC Rule

<group name="wordpress,">
  <rule id="102315" level="12">
    <decoded_as>web-access</decoded_as>
    <match>admin-ajax.php</match>
    <regex>action=relevanssi</regex>
    <regex>args=</regex>
    <regex>tax_query</regex>
    <regex>(?i)\x27\s*OR\s+\(?\s*(SELECT|IF|\x27)</regex>
    <description>Relevanssi Admin Search SQL Injection attempt (CVE-2026-15941)</description>
    <mitre>
      <id>T1190</id>
    </mitre>
    <group>attack.initial-access,</group>
    <options>no_full_log</options>
  </rule>

  <rule id="102316" level="14">
    <if_sid>102315</if_sid>
    <regex>(?i)SLEEP\s*\(|BENCHMARK\s*\(|UNION SELECT</regex>
    <description>Confirmed time-based blind SQLi payload in Relevanssi Admin Search (CVE-2026-15941)</description>
    <group>attack.initial-access,</group>
  </rule>
</group>

Mitigation & Patch Guidance

Patch Confidence: 0/4 — UNPATCHED — No patch evidence from any tracked source. The vendor has not released a fix as of this report.

1. Immediate Mitigations (until patch is available):

  • Restrict edit_posts capability: Audit all user roles. Remove edit_posts from contributor roles if business workflows permit. At minimum, restrict user registration to require manual approval.
  • Disable Relevanssi Admin Search: Temporarily deactivate the plugin's Admin Search feature by adding a code snippet to a custom mu-plugin or functions.php:
add_action('wp_ajax_relevanssi_admin_search', function() {
    wp_die('Admin Search disabled temporarily for security.');
}, 1);
  • Web Application Firewall (WAF) Rules: Deploy virtual patching rules that block POST requests to admin-ajax.php containing both action=relevanssi and SQL metacharacters (', --, SLEEP, BENCHMARK, UNION) in the args parameter.
  • Database Least Privilege: Ensure the WordPress database user has minimal permissions (SELECT, INSERT, UPDATE, DELETE only—no DROP, GRANT, or FILE).

2. Patch/Upgrade Steps:

  • Monitor for updates: Subscribe to the Relevanssi changelog RSS feed and the WordPress Plugin Security Tracker. The moment a patched version is released, upgrade immediately via wp plugin update relevanssi or the WordPress dashboard.
  • Verify patched version: After the vendor releases a fix, confirm that the code uses $wpdb->prepare() with %s placeholders for the taxonomy values before reinstating Admin Search.

3. Long-Term Hardening:

  • Regular Security Audits: Incorporate this vulnerability class into recurring WordPress plugin vulnerability scans (WPScan, Jetpack Scan).
  • Credential Policy: Enforce strong admin password policies. Time-based blind SQLi on password hashes is only dangerous if the hashes crack—mitigate by making admin passwords 16+ characters with high entropy.
  • Plugin Reduction: Evaluate whether Relevanssi is essential. For informational sites, native WordPress search may suffice. If retained, keep it updated religiously.
  • Web Server Logging: Enable and retain access logs for admin-ajax.php for at least 90 days to facilitate forensic investigations.
  • Network Segmentation: If the WordPress instance is in a DMZ, ensure the database is isolated on the internal network with strict firewall rules.

References

  1. NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-15941
  2. WordPress Plugin Repository: https://wordpress.org/plugins/relevanssi/
  3. Relevanssi Changelog: https://www.relevanssi.com/changelog/
  4. CWE-89 SQL Injection Reference: https://cwe.mitre.org/data/definitions/89.html
  5. ATT&CK T1190 Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/

Known Threat Actor Campaigns: No active in-the-wild exploitation campaigns have been identified as of this report, and the vulnerability is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog. However, given the plugin's large installed base and the low privilege requirement, high likelihood of weaponization exists. Security teams should treat this as a priority patching item upon vendor release.

👁️ SHODAN DORKS (THREAT HUNTING)

What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.

http.title:"Relevanssi"
http.component:"WordPress" http.title:"Admin Search"
http.component:"WordPress" http.body:"relevanssi"
http.title:"WordPress" http.body:"relevanssi_admin_search"

💣 PoC CODE AVAILABLE

Exploit code for this CVE is tracked in our database. Access poc_code via API Pro.

[ API_PRO ] →
◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-15941/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.