Admin Menu Editor <= 1.14.1 - Cross-Site Request Forgery
Description
The Admin Menu Editor plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 1.14.1. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action granted they can trick a site administrator into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:NTechnical Details
<=1.14.1What Changed in the Fix
Changes introduced in v1.15
Source Code
WordPress.org SVNThis research plan outlines the steps to verify the Cross-Site Request Forgery (CSRF) vulnerability in the **Admin Menu Editor** plugin (<= 1.14.1). ## 1. Vulnerability Summary The **Admin Menu Editor** plugin is vulnerable to CSRF because it fails to perform adequate nonce validation when saving t…
Show full research plan
This research plan outlines the steps to verify the Cross-Site Request Forgery (CSRF) vulnerability in the Admin Menu Editor plugin (<= 1.14.1).
1. Vulnerability Summary
The Admin Menu Editor plugin is vulnerable to CSRF because it fails to perform adequate nonce validation when saving the admin menu configuration. An attacker can trick a logged-in administrator into submitting a malicious POST request that overwrites the entire WordPress admin menu structure. This can be used to hide security settings, rename menu items to mislead administrators, or lock users out of specific admin areas.
2. Attack Vector Analysis
- Endpoint:
wp-admin/options-general.php?page=menu_editor(Legacy) orwp-admin/admin-ajax.php(Modern). - Action: The plugin typically uses a POST request to the settings page itself or an AJAX action named
ws_ame_save_menu(inferred from plugin history). - Vulnerable Parameters:
data(A JSON-encoded string representing the new menu structure),data_hash, andselected_actor. - Authentication Level: Unauthenticated (Attacker-side), but requires an authenticated Administrator to trigger the request via CSRF.
- Preconditions: The target administrator must have the
manage_optionscapability and be tricked into visiting a malicious page while logged into the WordPress dashboard.
3. Code Flow (Inferred)
- Entry Point: The plugin registers its menu page via
add_options_pagein a class (likelyameMenuEditor). - Request Handling: The function responsible for rendering the editor also checks for POST requests (e.g.,
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['data']))). - Vulnerability: The code likely checks for capabilities (
current_user_can('manage_options')) but missescheck_admin_referer()orcheck_ajax_referer(). - Data Processing: The
dataparameter is decoded and used to update thews_menu_editoroption in the database.
4. Nonce Acquisition Strategy
According to the vulnerability description, nonce validation is "missing or incorrect." If a nonce is required but uses a weak/default action, we can extract it.
- Identify Script Localization: The plugin enqueues its editor script and localizes data.
- Execution Agent Steps:
- Navigate to the editor page:
browser_navigate("/wp-admin/options-general.php?page=menu_editor") - Search for localized variables in the page source. Common candidates:
wsMenuEditorDataorameEditorData. - Use
browser_evalto extract the nonce:// Try common locations for AME nonces window.wsMenuEditorData?.nonce || window.ameEditorData?.nonce || "missing" - If
browser_evalreturns "missing" and the save request works without a_wpnonceorsecurityparameter, the nonce check is entirely absent.
- Navigate to the editor page:
5. Exploitation Strategy
We will simulate a CSRF attack by crafting a POST request that hides the "Plugins" menu.
Step-by-Step Plan:
- Identify current menu structure: First, we need a valid JSON payload. We will navigate to the menu editor as an admin and extract the current configuration.
- Craft Malicious Payload: Modify the JSON to set the
hiddenproperty totruefor theplugins-phpitem. - Trigger CSRF: Use
http_requestto send a POST request as the administrator (simulating the forged request).
HTTP Request Payload:
- URL:
http://localhost:8080/wp-admin/options-general.php?page=menu_editor - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body Parameters:
action:save_menu(or simply the POST target)data:[{"menu_title":"Dashboard",...},{"menu_title":"Plugins","file":"plugins.php","is_hidden":true,...}](URL-encoded JSON)data_hash: (If required, can be bypassed or pre-calculated)_wpnonce: (Only if identified in step 4, otherwise omit)
6. Test Data Setup
- Install Plugin: Ensure Admin Menu Editor v1.14.1 is installed and active.
- Verify Access: Ensure the admin can see the "Plugins" menu normally.
- Shortcode/Page: No specific shortcodes are needed as the vulnerability resides in the admin-facing editor page.
7. Expected Results
- The server should respond with a 302 redirect back to the menu editor page or a 200 OK (if AJAX).
- The
ws_menu_editoroption in the database will be updated. - The "Plugins" menu item will disappear from the WordPress admin sidebar for all users (or the targeted actor).
8. Verification Steps
- Database Check:
Check if the JSON containswp option get ws_menu_editor"is_hidden":truefor the plugins entry. - UI Check:
Navigate to the dashboard and verify the "Plugins" link is missing from the sidebar.
(The plugin will still be active, but invisible in the UI).wp plugin list --status=active
9. Alternative Approaches
If the POST to options-general.php fails:
- AJAX Route: Check for an AJAX handler
ws_ame_save_menu. Send the payload to/wp-admin/admin-ajax.phpwithaction=ws_ame_save_menu. - Incorrect Nonce: If a nonce is present but "incorrect," try using a nonce generated for a different action (e.g.,
-1) to see if it's accepted. - Actor Targeting: Target a specific role (e.g.,
editor) by setting theselected_actorparameter torole:editorin the POST request to restrict their access while leaving the admin's view intact (stealthier attack).
Summary
The Admin Menu Editor plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 1.14.1 due to missing or incorrect nonce validation when saving menu configurations. This allows unauthenticated attackers to overwrite the admin menu structure, hide menu items, or rename sections by tricking a logged-in administrator into performing an action like clicking a malicious link.
Security Fix
Only in /home/deploy/wp-safety.org/data/plugin-versions/admin-menu-editor/1.15/css: _collections.scss Only in /home/deploy/wp-safety.org/data/plugin-versions/admin-menu-editor/1.15/css: _dialogs.scss @@ -1084,6 +1084,27 @@ z-index: 10000; } +/* +Standard WordPress admin colors. + +Announcement post: +https://make.wordpress.org/core/2021/02/23/standardization-of-wp-admin-colors-in-wordpress-5-7/ + +Source: +https://codepen.io/ryelle/pen/WNGVEjw + +A "wp" prefix has been added to avoid name conflicts with other code in this plugin. + */ +.ui-dialog .ui-dialog-buttonpane { + background-color: #fcfcfc; + border-top: 1px solid #dcdcde; + padding: 8px; + text-align: right; +} +.ui-dialog .ui-dialog-buttonpane .button-primary, .ui-dialog .ui-dialog-buttonpane .ame-dialog-confirm-button { + float: left; +} + .settings_page_menu_editor .ui-dialog { background: white; border: 1px solid #c0c0c0; @@ -1882,6 +1903,29 @@ /********************************************* Miscellaneous **********************************************/ +#ws_ame_general_vis_box input[type=checkbox]:indeterminate:before { + content: "■"; + color: #1e8cbe; + margin: -3px 0 0 -1px; + font: 400 14px/1 dashicons; + float: left; + display: inline-block; + vertical-align: middle; + width: 16px; + -webkit-font-smoothing: antialiased; +} +@media screen and (max-width: 782px) { + #ws_ame_general_vis_box input[type=checkbox]:indeterminate:before { + height: 1.5625rem; + width: 1.5625rem; + line-height: 1.5625rem; + margin: -1px; + font-size: 18px; + font-family: unset; + font-weight: normal; + } +} + #ws_sidebar_pro_ad { min-width: 225px; max-width: 300px; ... (truncated)
Exploit Outline
The exploit targets the admin menu save functionality by forging a POST request. An attacker crafts a payload where the 'data' parameter contains a JSON-encoded string representing a modified admin menu structure (e.g., setting 'is_hidden' to true for the Plugins menu). This request is sent to the plugin's settings page (wp-admin/options-general.php?page=menu_editor) or via a specific AJAX action (ws_ame_save_menu). To execute the attack, the attacker tricks a logged-in administrator with 'manage_options' capabilities into visiting a malicious site or clicking a link that triggers the POST request via the victim's browser, bypassing the missing nonce check.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.