Advanced Custom Fields: Extended <= 0.9.2.1 - Unauthenticated Privilege Escalation via Insert User Form Action
Description
The Advanced Custom Fields: Extended plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 0.9.2.1. This is due to the 'insert_user' function not restricting the roles with which a user can register. This makes it possible for unauthenticated attackers to supply the 'administrator' role during registration and gain administrator access to the site. Note: The vulnerability can only be exploited if 'role' is mapped to the custom field.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=0.9.2.1Source Code
WordPress.org SVN# Research Plan: CVE-2025-14533 - Unauthenticated Privilege Escalation in ACF Extended ## 1. Vulnerability Summary The **Advanced Custom Fields: Extended (ACFE)** plugin (versions <= 0.9.2.1) contains a critical privilege escalation vulnerability. The plugin's "Frontend Forms" feature allows admini…
Show full research plan
Research Plan: CVE-2025-14533 - Unauthenticated Privilege Escalation in ACF Extended
1. Vulnerability Summary
The Advanced Custom Fields: Extended (ACFE) plugin (versions <= 0.9.2.1) contains a critical privilege escalation vulnerability. The plugin's "Frontend Forms" feature allows administrators to create forms that perform various actions, such as creating or updating WordPress users. The insert_user function within the User Action handler fails to validate or restrict the role parameter when it is mapped to a form field. Consequently, an unauthenticated user can submit a form and specify the administrator role, gaining full control over the site.
2. Attack Vector Analysis
- Endpoint: Any frontend page where an ACFE Form with a "User Action" is rendered.
- Action:
POSTrequest to the page URL containing the form. - Vulnerable Parameter: The ACF field input (e.g.,
acf[field_abc123]) that is mapped to the "Role" setting in the ACFE User Action configuration. - Authentication: Unauthenticated (if the form is public).
- Preconditions:
- An ACFE Form must be created and published.
- The form must have a "User" action configured to "Insert User".
- A field in that form must be mapped to the Role setting in the User Action configuration.
3. Code Flow (Inferred)
- Entry Point: A user submits a frontend form. WordPress processes the
POSTrequest. - Hook: ACF (and by extension ACFE) hooks into the request, typically via
acf/validate_save_postoracf/save_post. - Action Dispatch: ACFE's form handler identifies the "Actions" associated with the form.
- User Action Handler: The class handling the user action (likely
acfe_form_action_userinincludes/modules/form/actions/user.php) is invoked. - Sink: The
insert_usermethod is called. It retrieves values from the submittedacf[]array. If a field is mapped to 'role', the value is passed directly into an array that eventually reacheswp_insert_user(). - Vulnerability: There is no check to ensure the submitted role is within an allowed whitelist (e.g., 'subscriber') or that the submitter has the
promote_userscapability.
4. Nonce Acquisition Strategy
ACFE forms rely on standard ACF form security. To submit the form successfully, you need the _acf_nonce.
- Identify the Form Page: Locate a page where the ACFE form is rendered.
- Navigate and Extract:
- Use
browser_navigate(URL)to load the page. - Use
browser_eval()to extract the nonce and field keys. - Standard ACF nonce:
document.querySelector('input[name="_acf_nonce"]').value - Form ID:
document.querySelector('input[name="_acf_form"]').value - Field Key: Identify the key of the field mapped to the "Role" (e.g.,
field_67890abcdef). This can be found by inspecting thenameattribute of the inputs:acf[field_XXXXX].
- Use
5. Exploitation Strategy
Step 1: Payload Preparation
You need to identify the specific field key that ACFE is using for the role mapping. If you are setting up the test environment, you will know this key. In a real-world scenario, you would inspect the HTML source.
Step 2: HTTP Request
Submit a POST request to the page URL containing the form.
Headers:
Content-Type: application/x-www-form-urlencoded
Body Parameters:
_acf_nonce: [Extracted Nonce]_acf_form: [Extracted Encoded Form Data]acf[field_user_email]:attacker@example.comacf[field_user_login]:attacker_adminacf[field_user_password]:Password123!acf[field_mapped_to_role]:administrator<-- The Exploitacf[field_other_required_fields]: [Valid data]
Step 3: Execution
Use the http_request tool to send the POST request.
6. Test Data Setup
To replicate this in a lab environment:
- Install Plugins: Install
advanced-custom-fieldsandacf-extended(v0.9.2.1). - Create ACF Fields: Create a field group with at least:
- Email (Text field)
- Username (Text field)
- Password (Password field)
- Role (Text or Hidden field) - Crucial: This field will be manipulated.
- Create ACFE Form:
- Go to ACF -> Forms and create a new form.
- Add the field group created above.
- In the Actions tab, add a User action.
- Set Action to Insert User.
- In the User Data mapping section:
- Map Email to the Email field.
- Map Login to the Username field.
- Map Password to the Password field.
- Map Role to the Role field.
- Publish Form: Add the form to a new page using the shortcode provided by ACFE (e.g.,
[acfe_form ID="123"]).
7. Expected Results
- The server should return a
200 OKor a302 Redirect(standard ACF success behavior). - A new user should be created in the WordPress database.
- The new user should have the
administratorrole assigned.
8. Verification Steps
After sending the POST request, verify the success using wp-cli:
- Check User Existence:
wp user list --field=user_login | grep attacker_admin - Verify Role:
wp user get attacker_admin --field=roles- Success Criteria: The output must be
administrator.
- Success Criteria: The output must be
9. Alternative Approaches
- Hidden Fields: If the role is not a visible field but is still mapped in the background, check if adding the field key to the
POSTbody manually overrides the default role. - Update User: If "Insert User" is not available but "Update User" is, target an existing low-privileged account (if the form allows selecting a user to edit) and change its role to administrator by providing the role field key.
- Mapping to Other Privileged Fields: Check if other sensitive fields like
user_registeredor meta fields that control capabilities (e.g.,wp_capabilities) can be mapped and manipulated.
Summary
The Advanced Custom Fields: Extended plugin (<= 0.9.2.1) is vulnerable to unauthenticated privilege escalation via its Frontend Forms feature. When a form is configured with a 'User Action' set to 'Insert User' and a field is mapped to the 'Role' property, the plugin fails to validate the role value, allowing attackers to specify 'administrator' and gain full site access.
Exploit Outline
1. Identify a public page hosting an ACFE form configured with an 'Insert User' action. 2. Extract the field key mapped to the 'Role' attribute, as well as the '_acf_nonce' and '_acf_form' values from the HTML source. 3. Send a POST request to the form's URL with the mapped role field key set to 'administrator', alongside required username, email, and password fields. 4. If successful, a new administrator account will be created using the provided credentials.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.