CVE-2025-15463

Advanced Custom Fields: Extended <= 0.9.2.3 - Unauthenticated Arbitrary Shortcode Execution

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

Description

The The Advanced Custom Fields: Extended plugin for WordPress is vulnerable to arbitrary shortcode execution in all versions up to, and including, 0.9.2.3. This is due to the software allowing users to execute an action that does not properly validate a value before running do_shortcode. This makes it possible for unauthenticated attackers to execute arbitrary shortcodes.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=0.9.2.3
PublishedMay 12, 2026
Last updatedMay 12, 2026
Affected pluginacf-extended

What Changed in the Fix

Changes introduced in v0.9.2.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets **CVE-2025-15463**, an unauthenticated arbitrary shortcode execution vulnerability in the **Advanced Custom Fields: Extended (ACFE)** plugin. ### 1. Vulnerability Summary The vulnerability exists because the plugin registers an AJAX action accessible to unauthenticated us…

Show full research plan

This research plan targets CVE-2025-15463, an unauthenticated arbitrary shortcode execution vulnerability in the Advanced Custom Fields: Extended (ACFE) plugin.

1. Vulnerability Summary

The vulnerability exists because the plugin registers an AJAX action accessible to unauthenticated users (wp_ajax_nopriv_*) that accepts a shortcode parameter and passes it directly to the WordPress do_shortcode() function without adequate validation or capability checks. This allows an attacker to execute any registered shortcode on the site, potentially leading to information disclosure (e.g., via [contact-form-7], [gallery], or sensitive plugin-specific shortcodes) or further exploitation depending on available shortcodes.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Method: POST
  • Action: acfe/shortcode/render (inferred from ACFE field type naming conventions) or acfe/ajax/shortcode_render.
  • Vulnerable Parameter: shortcode
  • Authentication: Unauthenticated (wp_ajax_nopriv hook).
  • Preconditions: The plugin must be active. A valid WordPress nonce may be required if check_ajax_referer is used.

3. Code Flow

  1. Entry Point: The user sends a POST request to admin-ajax.php with action=acfe/shortcode/render.
  2. Hook Registration: The plugin registers the action:
    add_action('wp_ajax_nopriv_acfe/shortcode/render', 'acfe_ajax_shortcode_render');
  3. Vulnerable Function: The callback (likely acfe_ajax_shortcode_render) retrieves the shortcode parameter from $_POST.
  4. Processing: It calls do_shortcode($_POST['shortcode']).
  5. Sink: The output of the shortcode is echoed back to the user.

4. Nonce Acquisition Strategy

ACFE typically localizes nonces for its AJAX handlers. If the endpoint requires a nonce, it is likely tied to the acfe or acf JavaScript objects.

  1. Identify Trigger: ACFE's "Shortcode" field or "Form" module triggers the loading of these nonces.
  2. Setup Page: Create a page with an ACFE shortcode to ensure scripts are enqueued:
    wp post create --post_type=page --post_status=publish --post_title="Exploit" --post_content='[acfe_form]'
  3. Navigate: Use browser_navigate to the newly created page.
  4. Extract Nonce: Use browser_eval to extract the nonce from the global state.
    • Target: window.acfe?.nonce or window.acf?.get('nonce').
    • Alternative: Search page source for acfe localization: grep -oP '"nonce":"\K[a-f0-9]{10}'.

5. Exploitation Strategy

  1. Confirmation of Action Name:
    Grep the plugin directory for the vulnerable sink:
    grep -rn "do_shortcode" includes/
    Look for a function associated with a wp_ajax_nopriv action.
  2. Nonce Retrieval: (Follow strategy in Section 4).
  3. Payload Crafting:
    Prepare a POST request to admin-ajax.php.
    • action: (Identified action name, e.g., acfe/shortcode/render)
    • nonce: (Extracted nonce)
    • shortcode: [archives] or [recent_posts] (Standard WP shortcodes) or [acf_search] (ACFE specific).
  4. HTTP Request (Playwright):
    {
      "method": "POST",
      "url": "http://localhost:8080/wp-admin/admin-ajax.php",
      "headers": {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      "data": "action=acfe/shortcode/render&nonce=VALUE&shortcode=[archives]"
    }
    

6. Test Data Setup

  • Shortcode Verification: Ensure the [archives] or [recent_posts] shortcodes are available (they are standard in WP).
  • ACFE Content: Create an ACFE Form if needed to trigger the nonce leakage.
    # (Optional) Use ACFE functions if available via CLI to create a dummy form
    wp eval "acfe_import_form('{\"title\":\"Test Form\",\"name\":\"test_form\"}');"
    wp post create --post_type=page --post_status=publish --post_content='[acfe_form name="test_form"]'
    

7. Expected Results

  • The HTTP response should have a 200 OK status.
  • The response body should contain the rendered HTML of the shortcode (e.g., a list of monthly archives or recent posts).
  • If [wp_version] (a common test shortcode) is executed, it should return the current WordPress version string.

8. Verification Steps

  1. Response Analysis: Check the output of the http_request tool. If HTML lists (like archives) appear where they shouldn't, the execution is confirmed.
  2. Blind Verification: If the output is not returned directly, try a shortcode that performs an action, then verify with wp post list or wp option get.

9. Alternative Approaches

  • Action Name Search: If acfe/shortcode/render fails, search for other AJAX actions:
    grep -r "wp_ajax_nopriv" .
  • Nonce Bypass: Check if check_ajax_referer is called with die=false. If so, the nonce can be omitted or be invalid.
  • Nested Shortcodes: Try [[shortcode]] if the plugin uses a custom parsing wrapper.
  • Common ACFE Hooks: Check includes/fields/field-shortcode.php (if it exists) to see how the "Shortcode" field renders its preview.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Advanced Custom Fields: Extended plugin for WordPress is vulnerable to unauthenticated arbitrary shortcode execution. This occurs because the plugin registers an AJAX action that accepts a user-provided shortcode string and passes it directly to the WordPress do_shortcode function without sufficient validation or authorization checks.

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/acf-extended/0.9.2.3/acf-extended.php /home/deploy/wp-safety.org/data/plugin-versions/acf-extended/0.9.2.4/acf-extended.php
--- /home/deploy/wp-safety.org/data/plugin-versions/acf-extended/0.9.2.3/acf-extended.php	2026-01-15 03:36:48.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/acf-extended/0.9.2.4/acf-extended.php	2026-04-27 01:34:34.000000000 +0000
@@ -2,7 +2,7 @@
 /**
  * Plugin Name: Advanced Custom Fields: Extended
  * Description: All-in-one enhancement suite that improves WordPress & Advanced Custom Fields.
- * Version:     0.9.2.3
+ * Version:     0.9.2.4
  * Author:      ACF Extended
  * Plugin URI:  https://www.acf-extended.com
  * Author URI:  https://www.acf-extended.com
@@ -19,7 +19,7 @@
 class ACFE{
     
     // vars
-    var $version = '0.9.2.3';
+    var $version = '0.9.2.4';

Exploit Outline

The exploit targets the WordPress AJAX endpoint to execute arbitrary shortcodes without authentication. An attacker first retrieves a valid AJAX nonce, which is typically localized in the page source within the 'acfe' or 'acf' JavaScript objects (e.g., window.acfe.nonce). Once the nonce is obtained, the attacker sends a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to the vulnerable AJAX handler (likely acfe/ajax/shortcode_render) and the 'shortcode' parameter containing the target payload, such as [wp_version] or other sensitive shortcodes registered on the site. The server then returns the rendered output of the shortcode in the HTTP response.

Check if your site is affected.

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