CVE-2025-67540

Animation Addons for Elementor <= 2.4.5 - Authenticated (Contributor+) Arbitrary Content Deletion

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.4.6
Patched in
6d
Time to patch

Description

The Animation Addons for Elementor – GSAP Powered Elementor Addons & Website Templates plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.4.5. This makes it possible for authenticated attackers, with Contributor-level access and above, to delete arbitrary content.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.4.5
PublishedDecember 15, 2025
Last updatedDecember 20, 2025

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-67540 - Arbitrary Content Deletion ## 1. Vulnerability Summary The **Animation Addons for Elementor** plugin (up to version 2.4.5) is vulnerable to authenticated arbitrary content deletion. The vulnerability exists because an AJAX handler, specifically respons…

Show full research plan

Exploitation Research Plan: CVE-2025-67540 - Arbitrary Content Deletion

1. Vulnerability Summary

The Animation Addons for Elementor plugin (up to version 2.4.5) is vulnerable to authenticated arbitrary content deletion. The vulnerability exists because an AJAX handler, specifically responsible for deleting animations or related posts, fails to perform a capability check (e.g., current_user_can('edit_others_posts')). While the function implements a nonce check for CSRF protection, it does not verify if the authenticated user has the permissions to delete the specified post ID. This allows a user with Contributor level access to delete posts, pages, or templates created by other users, including Administrators.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: gsap_motion_delete_post (inferred from plugin functionality)
  • HTTP Method: POST
  • Payload Parameters:
    • action: gsap_motion_delete_post
    • post_id: The ID of the post/page to be deleted.
    • security or nonce: A valid WordPress nonce for the action.
  • Authentication: Required (Contributor level or higher).
  • Preconditions: The attacker must be logged in as a Contributor and have obtained a valid nonce.

3. Code Flow (Inferred)

  1. Registration: The plugin registers the AJAX action in an initialization class (likely includes/admin/class-admin.php or similar).
    add_action( 'wp_ajax_gsap_motion_delete_post', array( $this, 'gsap_motion_delete_post' ) );
    
  2. The Sink: The handler function gsap_motion_delete_post() is called.
    • It retrieves the post_id from $_POST.
    • It verifies the nonce using check_ajax_referer( 'gsap_motion_nonce', 'security' ).
    • Vulnerability: It lacks a call to current_user_can( 'delete_post', $post_id ) or current_user_can( 'manage_options' ).
    • It calls wp_delete_post( $post_id, true ).
  3. Execution: The WordPress core function wp_delete_post executes the deletion since the database-level check for the current user is often bypassed when called directly from a trusted internal handler that doesn't verify permissions first.

4. Nonce Acquisition Strategy

The plugin localizes admin scripts and includes a nonce. For a Contributor to exploit this, they must find a page in the WordPress admin where the plugin's admin script is enqueued.

  1. Identify Script Localization: The plugin likely uses wp_localize_script to pass a nonce to its admin JS.
    • Handle: gsap-motion-admin (inferred)
    • Object Name: gsap_motion_admin (inferred)
    • Nonce Key: nonce (inferred)
  2. Access Strategy:
    • Log in as the Contributor.
    • Navigate to the plugin's dashboard page (e.g., wp-admin/admin.php?page=gsap-motion-dashboard) or check if the scripts load on standard pages like wp-admin/edit.php.
    • Use browser_eval to extract the nonce:
      window.gsap_motion_admin?.nonce || window.gsap_motion_vars?.nonce
      
  3. Alternative: Check the page source for any JSON objects containing nonce and ajax_url.

5. Exploitation Strategy

Step 1: Authentication

Authenticate as a user with the Contributor role.

Step 2: Target Identification

Identify the ID of a "Target Post" created by the Administrator (e.g., Post ID 1).

Step 3: Nonce Extraction

  1. Use browser_navigate to go to /wp-admin/index.php or the plugin settings page.
  2. Use browser_eval to find the nonce variable.

Step 4: Deletion Request

Send a POST request to admin-ajax.php.

HTTP Request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application-x-www-form-urlencoded
Cookie: [Contributor Cookies]

action=gsap_motion_delete_post&post_id=[TARGET_POST_ID]&security=[NONCE]

(Note: If the parameter is not security, try nonce or _wpnonce).

6. Test Data Setup

  1. Create Target Content:
    • As Admin: Create a Page titled "Private Project" (ID will be used as the target).
    • wp post create --post_type=page --post_title="Private Project" --post_status=publish
  2. Create Attacker User:
    • wp user create attacker attacker@example.com --role=contributor --user_pass=password123
  3. Ensure Plugin Visibility:
    • Ensure the plugin is active and its admin menu is accessible to Contributors.

7. Expected Results

  • The AJAX response should be a JSON success message (e.g., {"success":true}).
  • The "Private Project" page should no longer exist in the WordPress database or should be in the trash.

8. Verification Steps

  1. Verify via WP-CLI:
    • Run wp post exists [TARGET_POST_ID]
    • Expected: Return empty/error indicating the post does not exist.
  2. Check Trash:
    • Run wp post list --post_status=trash --post_type=page
    • Check if the "Private Project" is listed.

9. Alternative Approaches

If the action gsap_motion_delete_post is incorrect, search the plugin source for other AJAX registrations:

  1. grep -r "wp_ajax_" wp-content/plugins/animation-addons-for-elementor/
  2. Look for any function calling wp_delete_post or $wpdb->delete.
  3. If the nonce is strictly protected, check if any wp_ajax_nopriv_ actions exist that allow access to the same deletion logic (unlikely but possible).
  4. If post_id is not the parameter name, try id or item_id.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Animation Addons for Elementor plugin (up to version 2.4.5) is vulnerable to authenticated arbitrary content deletion due to a missing capability check in an AJAX handler. This allows attackers with Contributor-level access or higher to delete any post, page, or template by providing its ID, as the plugin only validates a CSRF nonce but not user permissions.

Vulnerable Code

// Registration of the vulnerable AJAX handler (inferred from includes/admin/class-admin.php)
add_action( 'wp_ajax_gsap_motion_delete_post', array( $this, 'gsap_motion_delete_post' ) );

Security Fix

--- a/includes/admin/class-admin.php
+++ b/includes/admin/class-admin.php
@@ -10,6 +10,6 @@
 	$post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
 
-	if ( $post_id ) {
+	if ( $post_id && current_user_can( 'delete_post', $post_id ) ) {
 		wp_delete_post( $post_id, true );
 		wp_send_json_success();
 	}

Exploit Outline

The exploit is performed by an authenticated user with Contributor-level permissions or higher. The attacker first visits the WordPress admin area (e.g., the plugin's dashboard) to extract a valid CSRF nonce from localized JavaScript variables like 'gsap_motion_admin.nonce' or 'gsap_motion_vars.nonce'. Using this nonce, the attacker sends a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to 'gsap_motion_delete_post', the 'security' parameter containing the nonce, and the 'post_id' set to the target content's ID (such as an Administrator's private page). The plugin then executes 'wp_delete_post' on the specified ID without verifying if the requesting user has the authorization to delete that specific post.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.