Mail Mint – Email Marketing, Newsletter, Email Automation & WooCommerce Emails <= 1.19.5 - Authenticated (Subscriber+) Information Exposure
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:NTechnical Details
What Changed in the Fix
Changes introduced in v1.20.0
Source Code
WordPress.org SVN# 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()returnstrueunconditionally.Mint\MRM\Admin\API\Controllers\SettingBaseController::rest_permissions_check()returnstrueunconditionally.Mint\MRM\Admin\API\Routes\FieldGroupRouteexplicitly sets'permission_callback' => '__return_true'forREADABLE,CREATABLE, andEDITABLEmethods.
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 viaFieldGroupRoute.php)/wp-json/mrm/v1/campaigns/(Inferred fromServer.phpandAdminBaseController)/wp-json/mrm/v1/settings/(Inferred fromServer.phpandSettingBaseController)
- HTTP Method:
GET(for Information Exposure) - Authentication: Required (Subscriber level or higher)
- Preconditions: A valid
wp_restnonce must be provided in theX-WP-Nonceheader for authenticated REST requests.
3. Code Flow
- Route Registration:
Mint\MRM\Admin\API\Server::rest_api_init()iterates through routes defined inget_routes(). - Permission Setup: In
FieldGroupRoute::register_routes(), thepermission_callbackis set to__return_true. - Request Dispatch: When a Subscriber sends a GET request to
/wp-json/mrm/v1/field-groups/, WordPress calls thepermission_callback. - Bypass: Since the callback returns
true, the request proceeds toFieldGroupController::get_all(). - Data Retrieval:
FieldGroupController::get_all()callsMRM\Models\FieldGroup::get_all()(aliased fromModelsFieldGroup), 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.
- Login: Use the
browser_logintool to authenticate as a Subscriber. - Navigate: Navigate to the WordPress dashboard (
/wp-admin/). - Extraction: Use
browser_evalto extract the REST nonce from the default WordPresswpApiSettingsobject.- JavaScript:
window.wpApiSettings.nonce
- JavaScript:
- Action: Use this nonce in the
X-WP-Nonceheader for all subsequenthttp_requestcalls.
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 OKstatus 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:
- Create Subscriber: Use WP-CLI to create a user with the
subscriberrole. - Create Sensitive Data: Use WP-CLI (or
browser_evalas 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);" - 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 return401 Unauthorizedor403 Forbidden). - Data Content: The response should reveal
id,title, anddescriptionof field groups that should only be visible to administrators.
8. Verification Steps
- Check Response: Inspect the JSON returned by the
http_requesttool for the "Internal Sales Leads" field group. - 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
AdminBaseControllerwhich definesrest_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.phpthat return MailChimp configuration or list data.
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
@@ -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; } } @@ -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.