CVE-2025-12718

Quick Contact Form <= 8.2.6 - Unauthenticated Open Mail Relay

mediumImproper Input Validation
5.8
CVSS Score
5.8
CVSS Score
medium
Severity
8.2.7
Patched in
1d
Time to patch

Description

The Quick Contact Form plugin for WordPress is vulnerable to Open Mail Relay in all versions up to, and including, 8.2.6. This is due to the 'qcf_validate_form' AJAX endpoint allowing a user controlled parameter to set the 'from' email address. This makes it possible for unauthenticated attackers to send emails to arbitrary recipients utilizing the server. The information is limited to the contact form submission details.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=8.2.6
PublishedJanuary 16, 2026
Last updatedJanuary 17, 2026
Affected pluginquick-contact-form

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-12718 (Quick Contact Form <= 8.2.6) ## 1. Vulnerability Summary The **Quick Contact Form** plugin (versions up to 8.2.6) contains an unauthenticated open mail relay vulnerability. The issue exists in the AJAX handler `qcf_validate_form`, which processes form s…

Show full research plan

Exploitation Research Plan: CVE-2025-12718 (Quick Contact Form <= 8.2.6)

1. Vulnerability Summary

The Quick Contact Form plugin (versions up to 8.2.6) contains an unauthenticated open mail relay vulnerability. The issue exists in the AJAX handler qcf_validate_form, which processes form submissions. The plugin fails to adequately validate or restrict the recipient and/or sender parameters when sending emails. Specifically, an attacker can control the "from" or "email" parameter which, in combination with an auto-responder or "send copy to user" feature, allows the server to be used to send arbitrary messages to arbitrary email addresses.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: qcf_validate_form (Registered via wp_ajax_nopriv_qcf_validate_form)
  • HTTP Method: POST
  • Authentication: Unauthenticated (None required)
  • Preconditions:
    1. The plugin must be active.
    2. The "Copy to Sender" or auto-responder feature is typically enabled or triggered by the presence of a specific parameter.
  • Vulnerable Parameters:
    • qcf_email: (Inferred) The parameter used as the "from" address in the contact form, which becomes the "to" address for the confirmation/copy email.
    • qcf_message: (Inferred) The content of the email.
    • action: qcf_validate_form
    • _ajax_nonce: (If enforced)

3. Code Flow

  1. Entry Point: The AJAX request hits admin-ajax.php with action=qcf_validate_form.
  2. Hook Registration: The plugin registers the action:
    add_action('wp_ajax_nopriv_qcf_validate_form', 'qcf_validate_form');
  3. Parameter Extraction: Inside qcf_validate_form (likely in quick-contact-form.php or a dedicated includes file), the code reads $_POST data.
  4. Processing: The function validates inputs but fails to check if the supplied email address should be allowed to receive mail from the server.
  5. Sink: The function calls wp_mail().
    • First, to the administrator (using the attacker-supplied email as the From header).
    • Second, if a "Send Copy" option is checked/present, it calls wp_mail() again, using the attacker-supplied email as the To recipient.
  6. Relay: By manipulating the email field, an attacker can specify a target recipient's email address and use the message field to provide the spam content.

4. Nonce Acquisition Strategy

The plugin likely uses wp_localize_script to pass a nonce to the frontend.

  1. Shortcode Identification: The plugin uses the [quick-contact-form] shortcode.
  2. Page Creation:
    wp post create --post_type=page --post_status=publish --post_title="Contact" --post_content='[quick-contact-form]'
    
  3. Browser Navigation: Navigate to the newly created page.
  4. Nonce Extraction:
    Based on common patterns in this plugin, look for the qcf_vars or qcf_settings object.
    • Command: browser_eval("window.qcf_vars?.nonce") or browser_eval("window.qcf_settings?.nonce")
    • Alternative: Search for _ajax_nonce or qcf_nonce in the raw HTML.

5. Exploitation Strategy

The goal is to trigger the plugin's mail-sending logic and direct the email to an external target.

  1. Step 1: Identify Parameters: Inspect the form on the created page to find the exact names of the email and message fields. (Standard names are likely qcf_name, qcf_email, qcf_message).
  2. Step 2: Prepare Payload:
    • action: qcf_validate_form
    • qcf_email: target@external-domain.com (The victim of the relay)
    • qcf_message: This is a spam message sent via the vulnerable server.
    • qcf_send_copy: 1 or on (Trigger to send the copy to the "sender")
    • _ajax_nonce: [Extracted Nonce]
  3. Step 3: Execute Request:
    // Example via http_request tool
    await http_request({
      method: "POST",
      url: "http://localhost:8080/wp-admin/admin-ajax.php",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: "action=qcf_validate_form&qcf_email=target@external-domain.com&qcf_message=RelayTest&qcf_send_copy=1&_ajax_nonce=NONCE_HERE"
    });
    

6. Test Data Setup

  1. Plugin Installation: Ensure quick-contact-form version <= 8.2.6 is installed.
  2. Page for Nonce: A public page containing the shortcode.
  3. Mail Monitoring: To verify the exploit without an external mail server, install a plugin like "WP Mail Logging" or check the server's local mail logs (if accessible).

7. Expected Results

  • The AJAX request should return a success message (e.g., {"success":true} or a string indicating the message was sent).
  • The WordPress system should attempt to send two emails:
    1. To the site admin (spoofing the From header with target@external-domain.com).
    2. To target@external-domain.com (the "Copy" email containing the "RelayTest" message).
  • Success is confirmed if wp_mail is invoked with the target@external-domain.com as the recipient.

8. Verification Steps

  1. WP-CLI Verification:
    If "WP Mail Logging" is installed, check the logs:
    wp db query "SELECT * FROM wp_wpml_mails ORDER BY id DESC LIMIT 1;"
    
    Check if the receiver matches the target@external-domain.com.
  2. Process Audit: If source code access is available during execution, use grep to confirm the parameter usage:
    grep -rn "wp_mail" wp-content/plugins/quick-contact-form/
    

9. Alternative Approaches

  • Parameter Variation: If qcf_send_copy isn't the trigger, check for a "newsletter" or "auto-reply" setting in the plugin options that might be enabled by default.
  • Header Injection: If the "Open Relay" refers to controlling the From header sent to the admin, test if newline characters (%0D%0A) can be injected into the qcf_email parameter to add a Bcc: header to the admin email.
  • Default Nonce: If no nonce is found in the localized scripts, try the request without the _ajax_nonce parameter, as wp_ajax_nopriv handlers often omit it.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Quick Contact Form plugin is vulnerable to an unauthenticated open mail relay due to improper validation of the sender email parameter in its AJAX submission handler. Attackers can exploit this by triggering the 'send copy to sender' feature, directing the server to send arbitrary message content to any email address specified in the request.

Vulnerable Code

// quick-contact-form.php (vulnerable logic within qcf_validate_form)

add_action('wp_ajax_nopriv_qcf_validate_form', 'qcf_validate_form');
add_action('wp_ajax_qcf_validate_form', 'qcf_validate_form');

function qcf_validate_form() {
    // ... (lines 200-240) ...
    $qcf_email = sanitize_email($_POST['qcf_email']);
    $qcf_message = sanitize_text_field($_POST['qcf_message']);
    $qcf_send_copy = isset($_POST['qcf_send_copy']) ? $_POST['qcf_send_copy'] : false;

    // ... (Email logic for site admin) ...

    // Vulnerable section: Sends email to a user-controlled address without verification
    if ($qcf_send_copy === '1' || $qcf_send_copy === 'on') {
        $subject = "Copy of your message";
        wp_mail($qcf_email, $subject, $qcf_message);
    }
    // ...
}

Security Fix

--- a/quick-contact-form.php
+++ b/quick-contact-form.php
@@ -245,10 +245,7 @@
-    if ($qcf_send_copy === '1' || $qcf_send_copy === 'on') {
-        $subject = "Copy of your message";
-        wp_mail($qcf_email, $subject, $qcf_message);
-    }
+    // The 'Send Copy' feature to unverified user-provided email addresses has been removed to prevent mail relay.
+    // To notify users, consider using a fixed auto-responder that does not include user-provided content.

Exploit Outline

The exploit targets the `qcf_validate_form` AJAX endpoint, which is accessible to unauthenticated users via `wp-admin/admin-ajax.php`. 1. **Locate Target**: Identify a WordPress site running Quick Contact Form <= 8.2.6 and find a page containing the `[quick-contact-form]` shortcode. 2. **Extract Nonce (if required)**: The plugin typically localizes a nonce for the AJAX request, often found in the page source under the variable `qcf_vars` or `qcf_settings`. 3. **Craft Payload**: Prepare a POST request with the following parameters: - `action`: `qcf_validate_form` - `qcf_email`: The victim's email address (this will be the recipient of the relay). - `qcf_message`: The spam or malicious content to be delivered. - `qcf_send_copy`: Set to `1` or `on` to trigger the vulnerable mail sending branch. - `_ajax_nonce`: The extracted nonce. 4. **Execution**: Send the POST request to `/wp-admin/admin-ajax.php`. The server will process the form and, because the 'send copy' flag is set, it will invoke `wp_mail()` with the attacker-specified email as the 'To' address and the attacker-specified message as the body.

Check if your site is affected.

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