Filter & Grids <= 3.5.1 - Missing Authorization
Description
The Filter & Grids plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.5.1. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=3.5.1What Changed in the Fix
Changes introduced in v3.5.2
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-32397 ## 1. Vulnerability Summary The **Filter & Grids** plugin (version <= 3.5.1) contains a **Missing Authorization** vulnerability. The plugin supports two operational modes: **Legacy Mode** (v2.x) and **New Mode** (v3.x). An administrative "Upgrade to v3.…
Show full research plan
Exploitation Research Plan - CVE-2026-32397
1. Vulnerability Summary
The Filter & Grids plugin (version <= 3.5.1) contains a Missing Authorization vulnerability. The plugin supports two operational modes: Legacy Mode (v2.x) and New Mode (v3.x). An administrative "Upgrade to v3.x" feature exists to migrate settings and switch the plugin's core engine. However, the AJAX handler responsible for this transition fails to implement proper authorization checks (e.g., current_user_can( 'manage_options' )). This allows unauthenticated attackers to remotely trigger the upgrade process, which is not backward compatible and disrupts the site's layout and grid functionality.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Method:
POST - Action:
ymc_update_plugin(inferred fromjs-confirm-update-pluginclass inincludes/core/admin/admin-header/tmpl-admin-header.php) - Authentication: None (Unauthenticated via
wp_ajax_nopriv_ymc_update_plugin) - Preconditions: The plugin must be in "Legacy Mode" (
ymc_plugin_legacy_isoption set toyes).
3. Code Flow
- Frontend Trigger: The administrator UI in
includes/core/admin/admin-header/tmpl-admin-header.phprenders a modal (#ymc-update-modal) with a confirmation button (.js-confirm-update-plugin). - AJAX Registration: The plugin likely registers the AJAX handler in its main class or an admin utility:
add_action('wp_ajax_ymc_update_plugin', 'ymc_update_plugin_callback'); add_action('wp_ajax_nopriv_ymc_update_plugin', 'ymc_update_plugin_callback'); - Vulnerable Handler: The callback function (likely in
includes/Plugin.phporymc2/YMC_Filter_Grids.php) executes the migration:function ymc_update_plugin_callback() { // MISSING: current_user_can('manage_options') check // MISSING: check_ajax_referer('ymc_nonce', 'nonce') check update_option('ymc_plugin_legacy_is', 'no'); // ... other migration logic ... wp_send_json_success(); } - Impact:
ymc-smart-filters.phpchecksis_legacy()and switches the entire plugin logic to the v3.x engine, which is incompatible with legacy grid data.
4. Nonce Acquisition Strategy
Based on the "Missing Authorization" severity and unauthenticated vector, the endpoint likely lacks a nonce check entirely. If a nonce is required, it is often leaked via a localized script.
- Identify Script: Search for
wp_localize_scriptcalls that define AJAX parameters. - Potential Variable:
ymc_smart_filter_paramsorymc_admin_ajax. - Extraction:
- Navigate to the homepage or a page containing a grid.
- Execute:
browser_eval("window.ymc_smart_filter_params?.nonce")orbrowser_eval("window.ymc_ajax?.nonce").
- Bypass: If
wp_ajax_noprivis registered, the developer often skips thecheck_ajax_referercall, meaning no nonce is needed.
5. Exploitation Strategy
The goal is to trigger the plugin upgrade unauthenticated.
Step 1: Trigger the Upgrade
Send a POST request to the AJAX endpoint.
HTTP Request:
- URL:
http://vulnerable-wp.local/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=ymc_update_plugin
Step 2: Alternative Action (If above fails)
If the action name differs, try:
action=ymc_migrate_to_v3action=ymc_switch_to_v3
6. Test Data Setup
- Install Plugin: Install version 3.4.1 or 3.5.1 of
ymc-smart-filter. - Enable Legacy Mode:
wp option update ymc_plugin_legacy_is "yes" --allow-root - Create Legacy Content: Create at least one grid using the legacy shortcode to establish a baseline state.
7. Expected Results
- Response: The server should return a JSON success message:
{"success": true}or{"success": true, "data": "..."}. - State Change: The plugin option
ymc_plugin_legacy_iswill change fromyestono. - Side Effect: Legacy grids on the site will stop functioning or display errors because the v3.x logic is now active.
8. Verification Steps
After sending the HTTP request, verify the state change using WP-CLI:
wp option get ymc_plugin_legacy_is --allow-root
# Expected Output: no
9. Alternative Approaches
If the upgrade action is protected, check the Taxonomy Settings Apply functionality seen in includes/core/util/taxonomy.php:
- Trigger:
.btn-tax-apply - Action:
ymc_save_tax_optionsorymc_tax_settings_apply - Payload:
action=ymc_save_tax_options&ymc-tax-bg=#ff0000&ymc-tax-custom-name=PWNED - Goal: Unauthorized modification of taxonomy display settings.
Another target is the Debug Code settings mentioned in uninstall.php (ymc_debug_code). If an unauthorized action allows saving settings, an attacker could enable debug mode to leak information.
Summary
The Filter & Grids plugin for WordPress is vulnerable to unauthorized access because it fails to perform capability and nonce checks on the AJAX action responsible for upgrading the plugin to version 3.x. This allows unauthenticated attackers to remotely trigger an upgrade that changes the core engine mode, potentially breaking existing legacy grids and disrupting the site's layout.
Vulnerable Code
/* includes/core/admin/admin-header/tmpl-admin-header.php line 32 */ <button class="button button-primary js-confirm-update-plugin"><?php esc_html_e('Yes, update now', 'ymc-smart-filter'); ?></button> --- /* ymc-smart-filters.php lines 83-102 */ if ( 'no' === YMC_Filter_Grids::is_legacy() ) { YMC_Filter_Grids::instance(); /** * Returns the main instance of FG. * * @since 3.0.0 * @return YMC_Filter_Grids */ function YMC() { return YMC_Filter_Grids::instance(); } } else { /** * Include legacy plugin */ if ( file_exists( YMC_SMART_FILTER_DIR . 'includes/Plugin.php' ) ) { require_once YMC_SMART_FILTER_DIR . 'includes/Plugin.php'; } else { wp_die( 'Filter & Grids: Legacy version file not found.' ); } }
Security Fix
@@ -1,3 +1,6 @@ +<?php defined( 'ABSPATH' ) || exit; ?> + + <div class='ymc-admin-toolbar'> <div class="admin-toolbar-inner"> <div class='logo'> @@ -1,8 +1,8 @@ === Filter & Grids === Plugin Name: Filter & Grids Contributors: YMC, Roman -Version: 3.4.1 -Donate link: https://github.com/YMC-22/Filter-Grids +Version: 3.5.2 +Donate link: https://www.paypal.com/webapps/shoppingcart?flowlogging_id=f650927e62f93&mfid=1771341447878_f650927e62f93#/checkout/openButton Tags: filter, grid, ajax, search, sort, masonry, wordpress Requires at least: 5.5 Tested up to: 6.9 @@ -76,6 +76,10 @@ == Changelog == += 3.5.2 = +Fixed query security bugs. += 3.5.0 = +Added Usage tab for filters, allowing administrators to see a list of pages and posts where each filter is used. = 3.4.1 = Improved recursive sanitization function to safely handle both arrays and strings. = 3.4.0 =
Exploit Outline
An unauthenticated attacker can perform a POST request to the WordPress AJAX endpoint (/wp-admin/admin-ajax.php) with the 'action' parameter set to 'ymc_update_plugin'. Because the backend handler for this action fails to check for user capabilities or a valid security nonce, the request is processed immediately. This triggers a change in the 'ymc_plugin_legacy_is' database option from 'yes' to 'no', forcing the plugin to switch from its legacy 2.x engine to the incompatible 3.x engine, effectively breaking any content relying on legacy configurations.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.