CVE-2026-27349

Mail Mint – Email Marketing, Newsletter, Email Automation & WooCommerce Emails <= 1.19.5 - Authenticated (Subscriber+) Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.20.0
Patched in
6d
Time to patch

Description

The Mail Mint – Email Marketing, Newsletter, Email Automation & WooCommerce Emails plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.19.5. This makes it possible for authenticated attackers, with Subscriber-level access and above, to extract sensitive user or configuration data.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.19.5
PublishedMay 21, 2026
Last updatedMay 26, 2026
Affected pluginmail-mint

What Changed in the Fix

Changes introduced in v1.20.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-27349 ## 1. Vulnerability Summary The **Mail Mint** plugin (up to 1.19.5) contains an authentication bypass/improper authorization vulnerability in its REST API implementation. The plugin defines multiple administrative REST API endpoints under the `mrm/v1` n…

Show full research plan

Exploitation Research Plan - CVE-2026-27349

1. Vulnerability Summary

The Mail Mint plugin (up to 1.19.5) contains an authentication bypass/improper authorization vulnerability in its REST API implementation. The plugin defines multiple administrative REST API endpoints under the mrm/v1 namespace. However, the base controllers and the specific route registrations fail to implement proper capability checks.

Specifically:

  • Mint\MRM\Admin\API\Controllers\AdminBaseController::rest_permissions_check() returns true unconditionally.
  • Mint\MRM\Admin\API\Controllers\SettingBaseController::rest_permissions_check() returns true unconditionally.
  • Mint\MRM\Admin\API\Routes\FieldGroupRoute explicitly sets 'permission_callback' => '__return_true' for READABLE, CREATABLE, and EDITABLE methods.

This allows any authenticated user, such as a Subscriber, to access, read, and potentially modify administrative data like field groups, campaigns, and plugin settings.

2. Attack Vector Analysis

  • Endpoint Namespace: mrm/v1
  • Vulnerable Routes:
    • /wp-json/mrm/v1/field-groups/ (Confirmed via FieldGroupRoute.php)
    • /wp-json/mrm/v1/campaigns/ (Inferred from Server.php and AdminBaseController)
    • /wp-json/mrm/v1/settings/ (Inferred from Server.php and SettingBaseController)
  • HTTP Method: GET (for Information Exposure)
  • Authentication: Required (Subscriber level or higher)
  • Preconditions: A valid wp_rest nonce must be provided in the X-WP-Nonce header for authenticated REST requests.

3. Code Flow

  1. Route Registration: Mint\MRM\Admin\API\Server::rest_api_init() iterates through routes defined in get_routes().
  2. Permission Setup: In FieldGroupRoute::register_routes(), the permission_callback is set to __return_true.
  3. Request Dispatch: When a Subscriber sends a GET request to /wp-json/mrm/v1/field-groups/, WordPress calls the permission_callback.
  4. Bypass: Since the callback returns true, the request proceeds to FieldGroupController::get_all().
  5. Data Retrieval: FieldGroupController::get_all() calls MRM\Models\FieldGroup::get_all() (aliased from ModelsFieldGroup), which queries the database for all custom field groups and returns them to the unauthorized user.

4. Nonce Acquisition Strategy

To interact with the WordPress REST API as an authenticated user, a wp_rest nonce is required.

  1. Login: Use the browser_login tool to authenticate as a Subscriber.
  2. Navigate: Navigate to the WordPress dashboard (/wp-admin/).
  3. Extraction: Use browser_eval to extract the REST nonce from the default WordPress wpApiSettings object.
    • JavaScript: window.wpApiSettings.nonce
  4. Action: Use this nonce in the X-WP-Nonce header for all subsequent http_request calls.

5. Exploitation Strategy

The goal is to demonstrate that a Subscriber can access sensitive "Field Group" data created by an administrator.

Step 1: Unauthorized Information Retrieval

  • Tool: http_request
  • Method: GET
  • URL: /wp-json/mrm/v1/field-groups/
  • Headers:
    • X-WP-Nonce: [EXTRACTED_NONCE]
    • Content-Type: application/json
  • Expected Response: A 200 OK status with a JSON array containing the "Secret Field Group" details created during setup.

Step 2: Unauthorized Settings Retrieval (Secondary)

  • Method: GET
  • URL: /wp-json/mrm/v1/settings/
  • Headers:
    • X-WP-Nonce: [EXTRACTED_NONCE]
  • Expected Response: Configuration data for the Mail Mint plugin.

6. Test Data Setup

Before exploitation, administrative data must exist to be exposed:

  1. Create Subscriber: Use WP-CLI to create a user with the subscriber role.
  2. Create Sensitive Data: Use WP-CLI (or browser_eval as admin) to create a dummy field group.
    # Example using wp eval to simulate admin creating a group
    wp eval "use MRM\Models\FieldGroup; use MRM\Data\FieldGroup as DataFieldGroup; \$fg = new DataFieldGroup(['title' => 'Internal Sales Leads', 'description' => 'Confidential lead data']); MRM\Models\FieldGroup::insert(\$fg);"
    
  3. Verify Setup: Confirm the data exists in the database.

7. Expected Results

  • Success Criteria: The Subscriber receives a JSON response containing the string "Internal Sales Leads".
  • Status Code: 200 OK (If restricted, it would return 401 Unauthorized or 403 Forbidden).
  • Data Content: The response should reveal id, title, and description of field groups that should only be visible to administrators.

8. Verification Steps

  1. Check Response: Inspect the JSON returned by the http_request tool for the "Internal Sales Leads" field group.
  2. Database Comparison: Run wp db query "SELECT * FROM wp_mrm_field_groups;" (table name inferred from plugin prefix) and compare the results with the REST API output.

9. Alternative Approaches

If the field-groups endpoint is blocked for some reason, attempt to access the campaigns endpoint:

  • URL: /wp-json/mrm/v1/campaigns/
  • Logic: Inherits from AdminBaseController which defines rest_permissions_check() { return true; }. This should leak campaign titles and sender emails.

Another high-impact target is the contact-import list:

  • URL: /wp-json/mrm/v1/contact-import/ (GET)
  • Check: Look for any methods in ContactImportAction.php that return MailChimp configuration or list data.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Mail Mint plugin exposes sensitive administrative information through its REST API due to improper authorization checks in several base controllers and route definitions. Authenticated users, including those with Subscriber-level permissions, can access and potentially modify field groups, campaign data, and plugin settings by querying the 'mrm/v1' namespace.

Vulnerable Code

// app/API/Controllers/Admin/AdminBaseController.php
abstract class AdminBaseController extends BaseController {
	public function rest_permissions_check() {
		return true;
	}
}

---

// app/API/Controllers/Admin/SettingBaseController.php
abstract class SettingBaseController extends \WP_REST_Controller {
	public function rest_permissions_check() {
        return true;
	}
}

---

// app/API/Routes/Admin/FieldGroupRoute.php
register_rest_route(
	$this->namespace,
	'/' . $this->rest_base . '/',
	array(
		array(
			'methods'             => WP_REST_Server::CREATABLE,
			'callback'            => array($this->controller, 'create_or_update'),
			'permission_callback' => '__return_true',
		),
		array(
			'methods'             => \WP_REST_Server::READABLE,
			'callback'            => array($this->controller, 'get_all'),
			'permission_callback' => '__return_true',
		),
	)
);

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/mail-mint/1.19.5/app/API/Controllers/Admin/AdminBaseController.php /home/deploy/wp-safety.org/data/plugin-versions/mail-mint/1.20.0/app/API/Controllers/Admin/AdminBaseController.php
--- /home/deploy/wp-safety.org/data/plugin-versions/mail-mint/1.19.5/app/API/Controllers/Admin/AdminBaseController.php	2024-12-06 09:53:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/mail-mint/1.20.0/app/API/Controllers/Admin/AdminBaseController.php	2026-03-16 08:49:44.000000000 +0000
@@ -29,6 +29,13 @@
 	 * @since 1.0.0
 	 */
     public function rest_permissions_check() {
+		if ( ! current_user_can( 'manage_options' ) ) {
+			return new \WP_Error(
+				'rest_forbidden',
+				__( 'Sorry, you are not authorized to perform this action.', 'mrm' ),
+				array( 'status' => rest_authorization_required_code() )
+			);
+		}
 		return true;
 	}
 }
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/mail-mint/1.19.5/app/API/Controllers/Admin/SettingBaseController.php /home/deploy/wp-safety.org/data/plugin-versions/mail-mint/1.20.0/app/API/Controllers/Admin/SettingBaseController.php
--- /home/deploy/wp-safety.org/data/plugin-versions/mail-mint/1.19.5/app/API/Controllers/Admin/SettingBaseController.php	2024-12-06 09:53:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/mail-mint/1.20.0/app/API/Controllers/Admin/SettingBaseController.php	2026-03-16 08:49:44.000000000 +0000
@@ -97,7 +97,14 @@
 	 * @since 1.0.0
 	 */
 	public function rest_permissions_check() {
-		return true;
+		if ( ! current_user_can( 'manage_options' ) ) {
+			return new \WP_Error(
+				'rest_forbidden',
+				__( 'Sorry, you are not authorized to perform this action.', 'mrm' ),
+				array( 'status' => rest_authorization_required_code() )
+			);
+		}
+		return true;
 	}

Exploit Outline

To exploit this vulnerability, an attacker first authenticates as a Subscriber-level user and obtains a valid REST API nonce (X-WP-Nonce) from the dashboard. The attacker then sends a GET request to administrative endpoints such as /wp-json/mrm/v1/field-groups/, /wp-json/mrm/v1/campaigns/, or /wp-json/mrm/v1/settings/. Because the plugin's permission callbacks for these routes and their base controllers return true for any logged-in user without checking for administrative capabilities (manage_options), the plugin returns sensitive configuration data, user-defined custom field groups, or email campaign details that should only be accessible to administrators.

Check if your site is affected.

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