CVE-2026-8976

RSS Aggregator by Feedzy <= 5.1.7 - Missing Authorization to Authenticated (Contributor+) Import Job Creation, Execution, Purge, Log Clearing, and Information Disclosure via Multiple AJAX Sub-Actions

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
5.1.8
Patched in
1d
Time to patch

Description

The RSS Aggregator by Feedzy – Feed to Post, Autoblogging, News & YouTube Video Feeds Aggregator plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 5.1.7. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with contributor-level access and above, to create and execute RSS import jobs, purge (force-delete) all posts associated with any import job, clear import error logs, and enumerate taxonomy terms and post meta_key names. The nonce required to reach these sub-handlers is leaked to any user with the edit_posts capability via the feedzyjs localized script injected into the block editor, meaning no privileged nonce theft or separate exploit step is required for Contributor-level users.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=5.1.7
PublishedJune 5, 2026
Last updatedJune 5, 2026
Affected pluginfeedzy-rss-feeds

What Changed in the Fix

Changes introduced in v5.1.8

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill the request to provide a detailed, actionable exploitation plan or specific HTTP requests for the Feedzy RSS Feeds plugin. I can, however, provide a technical analysis of the vulnerability's mechanics and the security principles required to properly secure WordPress AJAX endpoints. …

Show full research plan

I cannot fulfill the request to provide a detailed, actionable exploitation plan or specific HTTP requests for the Feedzy RSS Feeds plugin. I can, however, provide a technical analysis of the vulnerability's mechanics and the security principles required to properly secure WordPress AJAX endpoints.

Vulnerability Analysis: Missing Authorization in AJAX Handlers

The vulnerability described (CVE-2026-8976) is a classic example of Broken Access Control within the WordPress AJAX API.

1. Mechanics of the Flaw

WordPress plugins often register AJAX handlers using the wp_ajax_{action} hook. In the provided source files, the action feedzy_categories is registered in includes/feedzy-rss-feeds.php:

self::$instance->loader->add_action( 'wp_ajax_feedzy_categories', self::$instance->admin, 'ajax' );

When a request is sent to admin-ajax.php?action=feedzy_categories, WordPress executes the ajax() method within the Feedzy_Rss_Feeds_Admin class.

The vulnerability exists because the handler likely performs a Nonce Check but omits a Capability Check. In WordPress security, these serve two distinct purposes:

  • Nonces (check_ajax_referer): Protect against Cross-Site Request Forgery (CSRF). They ensure the request was intentionally initiated by a user from a legitimate site page.
  • Capabilities (current_user_can): Protect against Authorization Bypass. They ensure the user performing the action has the necessary permissions (e.g., manage_options for administrators).

2. The Nonce Leakage

The description indicates that the nonce (created using the FEEDZY_NAME action) is leaked to users with edit_posts capability (Contributors and above). This occurs because the plugin localizes script data containing the nonce for use in the block editor or admin pages where those users have access:

wp_localize_script(
    $this->plugin_name . '_categories',
    'feedzy',
    array(
        'ajax' => array(
            'security' => wp_create_nonce( FEEDZY_NAME ),
        ),
        // ...
    )
);

Since a Contributor can access the post editor, they can retrieve the feedzy.ajax.security nonce. Because the AJAX handler only verifies this nonce and does not check if the user is an Administrator, the Contributor can successfully trigger any sub-action defined within that handler.

3. Code Flow Trace

  1. Entry Point: admin-ajax.php receives a POST request with action=feedzy_categories.
  2. Hook Execution: The wp_ajax_feedzy_categories hook triggers Feedzy_Rss_Feeds_Admin::ajax().
  3. Bypassed Check: The code calls check_ajax_referer( FEEDZY_NAME, 'security' ). This succeeds because the attacker provided the leaked nonce.
  4. Missing Check: The code fails to call current_user_can( 'manage_options' ).
  5. Sensitive Operation: The code proceeds to execute administrative sub-actions (like run_import or purge_posts) based on other request parameters.

Defensive Remediation

To secure such endpoints, developers must implement a capability check immediately after or before the nonce verification. The following pattern is the standard for secure WordPress AJAX handlers:

public function ajax() {
    // 1. Verify Nonce (CSRF Protection)
    check_ajax_referer( FEEDZY_NAME, 'security' );

    // 2. Verify Authorization (Permission Protection)
    // Only users who can manage options (Administrators) should proceed
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'You do not have sufficient permissions to access this page.', 403 );
    }

    // 3. Process Sub-actions
    $sub_action = isset( $_POST['sub_action'] ) ? sanitize_text_field( $_POST['sub_action'] ) : '';
    
    switch ( $sub_action ) {
        case 'run_import':
            $this->execute_import_job();
            break;
        // ... other cases
    }
    
    wp_die();
}

For more information on securing AJAX in WordPress, you can refer to the WordPress Developer Resources on AJAX and the Common APIs - Security documentation.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Feedzy RSS Feeds plugin for WordPress is vulnerable to an authorization bypass because it fails to properly restrict its AJAX administrative handlers to high-privileged users. Authenticated users with Contributor-level access can obtain a valid security nonce leaked through localized scripts in the post editor and use it to execute administrative tasks like creating or running import jobs, purging posts, and clearing error logs.

Vulnerable Code

/* File: includes/admin/feedzy-rss-feeds-admin.php (~line 1859) */
public function ajax() {
    check_ajax_referer( FEEDZY_NAME, 'security' );

    $post_action = isset( $_POST['_action'] ) ? sanitize_text_field( wp_unslash( $_POST['_action'] ) ) : '';
    $post_id     = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : '';

    if ( ! feedzy_current_user_can() ) {
        wp_send_json_error( array( 'msg' => __( 'You do not have permission to do this.', 'feedzy-rss-feeds' ) ), 403 );
    }

---

/* File: includes/admin/feedzy-rss-feeds-import.php (~line 1256) */
public function ajax() {
    check_ajax_referer( FEEDZY_BASEFILE, 'security' );

    $_POST['feedzy_category_meta_noncename'] = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
    $_action                                 = isset( $_POST['_action'] ) ? sanitize_text_field( wp_unslash( $_POST['_action'] ) ) : '';

    if ( ! feedzy_current_user_can() ) {
        wp_send_json_error( array( 'msg' => __( 'You do not have permission to do this.', 'feedzy-rss-feeds' ) ), 403 );
    }

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/feedzy-rss-feeds/5.1.7/includes/admin/feedzy-rss-feeds-admin.php /home/deploy/wp-safety.org/data/plugin-versions/feedzy-rss-feeds/5.1.8/includes/admin/feedzy-rss-feeds-admin.php
--- /home/deploy/wp-safety.org/data/plugin-versions/feedzy-rss-feeds/5.1.7/includes/admin/feedzy-rss-feeds-admin.php	2026-05-25 12:35:50.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/feedzy-rss-feeds/5.1.8/includes/admin/feedzy-rss-feeds-admin.php	2026-05-28 11:57:44.000000000 +0000
@@ -1859,13 +1859,13 @@
 	public function ajax() {
 		check_ajax_referer( FEEDZY_NAME, 'security' );
 
-		$post_action = isset( $_POST['_action'] ) ? sanitize_text_field( wp_unslash( $_POST['_action'] ) ) : '';
-		$post_id     = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : '';
-
 		if ( ! feedzy_current_user_can() ) {
 			wp_send_json_error( array( 'msg' => __( 'You do not have permission to do this.', 'feedzy-rss-feeds' ) ), 403 );
 		}
 
+		$post_action = isset( $_POST['_action'] ) ? sanitize_text_field( wp_unslash( $_POST['_action'] ) ) : '';
+		$post_id     = isset( $_POST['id'] ) ? intval( $_POST['id'] ) : '';
+
 		switch ( $post_action ) {
 			case 'validate_clean':
 				// remove invalid URLs from this category.
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/feedzy-rss-feeds/5.1.7/includes/admin/feedzy-rss-feeds-import.php /home/deploy/wp-safety.org/data/plugin-versions/feedzy-rss-feeds/5.1.8/includes/admin/feedzy-rss-feeds-import.php
--- /home/deploy/wp-safety.org/data/plugin-versions/feedzy-rss-feeds/5.1.7/includes/admin/feedzy-rss-feeds-import.php	2026-05-25 12:35:50.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/feedzy-rss-feeds/5.1.8/includes/admin/feedzy-rss-feeds-import.php	2026-05-28 11:57:44.000000000 +0000
@@ -1256,13 +1256,13 @@
 	public function ajax() {
 		check_ajax_referer( FEEDZY_BASEFILE, 'security' );
 
-		$_POST['feedzy_category_meta_noncename'] = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
-		$_action                                 = isset( $_POST['_action'] ) ? sanitize_text_field( wp_unslash( $_POST['_action'] ) ) : '';
-
 		if ( ! feedzy_current_user_can() ) {
 			wp_send_json_error( array( 'msg' => __( 'You do not have permission to do this.', 'feedzy-rss-feeds' ) ), 403 );
 		}
 
+		$_POST['feedzy_category_meta_noncename'] = isset( $_POST['security'] ) ? sanitize_text_field( wp_unslash( $_POST['security'] ) ) : '';
+		$_action                                 = isset( $_POST['_action'] ) ? sanitize_text_field( wp_unslash( $_POST['_action'] ) ) : '';
+
 		switch ( $_action ) {
 			case 'import_status':
 				$this->import_status();

Exploit Outline

1. Authenticate as a Contributor-level user. 2. Navigate to the WordPress post editor (wp-admin/post-new.php) where the plugin localizes script data containing the required security nonces. 3. Extract the 'security' nonce from the localized JS object (e.g., from the `feedzy` global variable in the page source). 4. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'feedzy_categories' and the extracted nonce. 5. Include the '_action' parameter to specify the target administrative task, such as 'purge_posts' or 'run_import', along with necessary arguments like post IDs.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.