CVE-2025-11370

Depicter <= 4.0.7 - Missing Authorization to Unauthenticated Display Rule Updates

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.7.0
Patched in
1d
Time to patch

Description

The Popup and Slider Builder by Depicter – Add Email collecting Popup, Popup Modal, Coupon Popup, Image Slider, Carousel Slider, Post Slider Carousel plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the 'store' function of the RulesAjaxController class in all versions up to, and including, 4.0.7. This makes it possible for unauthenticated attackers to update pop-up display settings.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.0.7
PublishedJanuary 5, 2026
Last updatedJanuary 6, 2026
Affected plugindepicter

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2025-11370 - Depicter Unauthorized Display Rule Updates ## 1. Vulnerability Summary The **Depicter** plugin (versions <= 4.0.7) contains a missing authorization vulnerability in the `RulesAjaxController::store` method. This vulnerability allows unauthenticated attackers to modi…

Show full research plan

Research Plan: CVE-2025-11370 - Depicter Unauthorized Display Rule Updates

1. Vulnerability Summary

The Depicter plugin (versions <= 4.0.7) contains a missing authorization vulnerability in the RulesAjaxController::store method. This vulnerability allows unauthenticated attackers to modify the display rules (e.g., where a popup appears, timing, audience targeting) of any slider or popup created with the plugin. The flaw exists because the AJAX handler responsible for saving rules fails to verify the user's capabilities, and likely exposes a nopriv (unauthenticated) AJAX action or fails to properly protect the authenticated one.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: depicter_ajax (inferred based on Depicter's common dispatcher pattern)
  • Parameters:
    • controller: rules (inferred)
    • method: store (referenced in the CVE description)
    • nonce: A security nonce (required if check_ajax_referer is present).
    • data: Likely a JSON object or array containing slider_id and the new rules configuration.
  • Authentication: Unauthenticated (via wp_ajax_nopriv_ registration).
  • Preconditions: At least one Depicter slider or popup must exist on the site for its rules to be modified.

3. Code Flow (Inferred)

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php.
  2. Hook Registration: The plugin registers an AJAX action:
    add_action('wp_ajax_nopriv_depicter_ajax', array($dispatcher, 'handle'));
  3. Dispatcher: The dispatcher parses the controller and method parameters.
  4. Vulnerable Sink: The dispatcher calls RulesAjaxController->store().
  5. Missing Check: Inside store(), the code likely retrieves the slider ID and rule data from $_POST['args'] or $_POST['data'] and saves them to the database (likely in the wp_depicter_sliders table or via update_post_meta) without calling current_user_can('manage_options').

4. Nonce Acquisition Strategy

Depicter typically localizes a common configuration object for its editor and frontend.

  1. Identify Shortcode: The plugin uses [depicter id="ID_HERE"].
  2. Create Test Page:
    wp post create --post_type=page --post_status=publish --post_title="Depicter Test" --post_content='[depicter id="1"]' (Replace 1 with an actual slider ID).
  3. Extract Nonce: Use the browser to find the localized script data.
    • Variable Name: depicterCommon or depicterRules (inferred).
    • Extraction Command:
      browser_eval("window.depicterCommon?.nonce || window.depicter_ajax?.nonce")
  4. Action Check: If the wp_ajax_nopriv_ action is used, the nonce is likely generated with an action string like depicter_ajax_nonce or depicter-nonce.

5. Exploitation Strategy

The goal is to modify the display rules of an existing slider to show it on every page, potentially for defacement or to inject malicious links if the rules allow custom HTML/content display.

Step-by-Step Plan:

  1. Identify Target Slider: Use wp_cli to find an existing slider ID:
    wp db query "SELECT id FROM wp_depicter_sliders LIMIT 1;"
  2. Obtain Nonce: Navigate to any page where Depicter is loaded and extract the nonce using browser_eval.
  3. Craft Payload: The store method likely expects a payload representing display logic.
    • URL: http://vulnerable-wp.local/wp-admin/admin-ajax.php
    • Method: POST
    • Body (URL-encoded):
      action=depicter_ajax
      &controller=rules
      &method=store
      &nonce=[EXTRACTED_NONCE]
      &args[slider_id]=[TARGET_ID]
      &args[rules]={"display":{"all":true},"trigger":{"time":0}}
      
      (Note: Exact args structure must be verified by inspecting the RulesAjaxController.php file in the plugin directory.)

6. Test Data Setup

  1. Install Depicter: Ensure Depicter <= 4.0.7 is active.
  2. Create a Slider: Use the plugin UI or wp_cli to create a basic slider so a record exists in the database.
  3. Publish Slider: Note the ID (e.g., 1).
  4. Create Public Page: Create a page containing the slider shortcode to ensure nonces are generated and accessible to unauthenticated users.

7. Expected Results

  • Response: The server should return a 200 OK with a JSON response, likely {"success": true}.
  • State Change: The display rules for the slider in the database will be updated to the values provided in the attack payload.

8. Verification Steps

  1. Database Check: Query the database to see if the rules changed for the specific slider:
    wp db query "SELECT rules FROM wp_depicter_sliders WHERE id = [TARGET_ID];"
  2. Frontend Observation: Visit the site homepage (or a page where the slider wasn't previously supposed to show) and verify that the slider now appears based on the new "Display Everywhere" rule.

9. Alternative Approaches

  • Check for direct Rule Controller: If the dispatcher depicter_ajax is not the entry point, check for direct action registrations like wp_ajax_nopriv_depicter_rules_store.
  • JSON Payload: Some Depicter versions may expect the entire body as a JSON object rather than standard POST parameters. If application/x-www-form-urlencoded fails, try application/json.
  • Parameter Names: If args or data fails, search the plugin source for $_POST or $_REQUEST in app/Controller/Ajax/RulesAjaxController.php to identify the correct parameter names.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Depicter plugin for WordPress is vulnerable to unauthorized display rule updates due to a missing capability check in its AJAX handling logic. This allows unauthenticated users to modify where and when sliders or popups are displayed on a site.

Vulnerable Code

/* File: app/Controller/Ajax/RulesAjaxController.php (inferred) */
// Missing current_user_can() check in the store method
public function store($args) {
    $slider_id = $args['slider_id'];
    $rules = $args['rules'];
    
    // Directly saving rules without authorization check
    $this->sliderRepository->updateRules($slider_id, $rules);
    
    wp_send_json_success();
}

Security Fix

--- a/app/Controller/Ajax/RulesAjaxController.php
+++ b/app/Controller/Ajax/RulesAjaxController.php
@@ -12,6 +12,10 @@
     public function store($args) {
+        if (!current_user_can('manage_options')) {
+            wp_send_json_error('Unauthorized', 403);
+            return;
+        }
+        
         $slider_id = $args['slider_id'];

Exploit Outline

The exploit targets the WordPress AJAX endpoint using the 'depicter_ajax' action. An attacker first extracts a security nonce from the frontend of a site where a Depicter slider is active. They then send a POST request to wp-admin/admin-ajax.php with parameters specifying the 'rules' controller and 'store' method. The payload includes a targeted slider ID and a new set of display rules (e.g., setting the slider to display on all pages) in the 'args' parameter. Since the 'store' method lacks an authorization check (like current_user_can), the request succeeds regardless of the attacker's login status.

Check if your site is affected.

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