Frontend Admin by DynamiApps <= 3.28.36 - Unauthenticated Privilege Escalation via Edit User Form
Description
The Frontend Admin by DynamiApps plugin for WordPress is vulnerable to Privilege Escalation in versions up to and including 3.28.36. This is due to insufficient authorization checks in the role field update mechanism combined with overly permissive capabilities for the admin_form post type. The admin_form custom post type uses 'capability_type' => 'page', which grants editors the ability to create and edit forms. When an editor creates an edit_user form, they can manipulate the form configuration to include 'administrator' in the role_options array by directly submitting POST data to wp-admin/post.php, bypassing the UI restrictions in feadmin_get_user_roles(). When the form is subsequently submitted, the pre_update_value() function in class-role.php only validates that the submitted role exists in the form's role_options array (lines 107-110), but fails to verify that the current user has permission to assign that specific role. This makes it possible for unauthenticated attackers to first register as editors (via a public new_user form), then create an edit_user form with administrator in the allowed roles, and finally use that form to escalate their own privileges to administrator.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=3.28.36What Changed in the Fix
Changes introduced in v3.29.1
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-6228 ## 1. Vulnerability Summary The **Frontend Admin by DynamiApps** plugin (<= 3.28.36) contains a privilege escalation vulnerability. The root cause is a combination of overly permissive access to the `admin_form` custom post type and insufficient validati…
Show full research plan
Exploitation Research Plan - CVE-2026-6228
1. Vulnerability Summary
The Frontend Admin by DynamiApps plugin (<= 3.28.36) contains a privilege escalation vulnerability. The root cause is a combination of overly permissive access to the admin_form custom post type and insufficient validation in the user role update logic.
Because the admin_form post type uses 'capability_type' => 'page', any user with the Editor role can create and modify these forms. An attacker can register as an Editor (using a public "New User" form), create an "Edit User" form, and manipulate the form's configuration via wp-admin/post.php to include the administrator role in the allowed roles list (role_options). The plugin's validation logic in class-role.php::pre_update_value() only checks if the submitted role is in the form's allowed list but fails to check if the user performing the update has the authority to assign that specific role.
2. Attack Vector Analysis
- Vulnerable Endpoints:
wp-admin/post.php: Used by an Editor to save theadmin_formconfiguration.admin-ajax.phpor the frontend form submission path: Used to submit the "Edit User" form.
- Authentication: Requires Editor privileges. However, the vulnerability description suggests an unauthenticated attacker can reach this by first using a public "New User" form to register as an Editor.
- Payloads:
- A POST request to
post.phpto update anadmin_form's metadata, injecting'administrator'into therole_optionsarray. - A frontend POST request (form submission) to change the current user's role.
- A POST request to
- Preconditions:
- Plugin must be active.
- An "Edit User" form must be created by the attacker (as an Editor).
3. Code Flow
- Entry Point 1 (Configuration): Editor visits
wp-admin/post.phpto save anadmin_form. - Sink 1: The
admin_formsettings are saved. The attacker intercepts the save request and addsadministratorto therole_optionsfield (likely an ACF-based field). - Entry Point 2 (Execution): The attacker navigates to the frontend page where the "Edit User" form is rendered.
- Processing: The form is submitted. The plugin calls
pre_update_value()inmain/fields/class-role.php(inferred path). - Vulnerable Logic:
// main/fields/class-role.php (logic described in vulnerability) public function pre_update_value($value, $post_id, $field) { $role_options = $field['role_options']; // Attacker controlled via configuration if (in_array($value, $role_options)) { return $value; // Validates against form config, NOT WP capabilities } } - Sink 2: The user's role is updated via
wp_update_user()orWP_User::set_role().
4. Nonce Acquisition Strategy
The plugin uses nonces for form submission and AJAX actions. Since we need to act as an Editor first, we can extract nonces from the page source.
- Form Configuration Nonce: When editing the
admin_formin the dashboard, the standard WordPress_wpnonceforpost.phpis required. - Frontend Form Nonce: The frontend forms (ACF Frontend) typically localize a nonce.
- Action: Look for
wp_localize_scriptcalls in the source. - JS Variable: Likely
frontend_adminoracf_frontend. - Key:
nonceorajax_nonce.
- Action: Look for
- Acquisition Steps:
- Create a page with the form:
wp post create --post_type=page --post_status=publish --post_content='[acf_frontend_form form_id="XXX"]'. - Navigate to the page using
browser_navigate. - Execute:
browser_eval("window.acf_frontend?.nonce")or check for hidden input_acf_nonce.
- Create a page with the form:
5. Exploitation Strategy
Phase 1: Unauthenticated Editor Registration
- Goal: Register a new user with the "Editor" role.
- Action: Locate a public "New User" form created by the plugin. If none exists, find the shortcode and create one via WP-CLI.
- Payload: Submit the registration form, ensuring the
roleparameter (if hidden) is set toeditor.
Phase 2: Form Configuration Manipulation
- Goal: Create/Edit an "Edit User" form and allow it to assign the "Administrator" role.
- Request:
POST /wp-admin/post.php - Parameters:
action:editpostpost_ID: The ID of theadmin_form.- Find the ACF field key for
role_options. It will likely look likeacf[field_xxxxxx]. - Inject
administratorinto the array:acf[field_xxxxxx][]=administrator.
Phase 3: Privilege Escalation
- Goal: Use the manipulated form to escalate the Editor account to Administrator.
- Request:
POSTto the page containing the form (oradmin-ajax.phpif it's an AJAX form). - Parameters:
acf[field_role_key]:administrator_acf_form: Base64 encoded form settings._acf_nonce: Extracted from the frontend page.
6. Test Data Setup
- Plugin Setup: Ensure
acf-frontend-form-elementis active. - Form Creation:
- Use WP-CLI to create an
admin_formpost:wp post create --post_type=admin_form --post_title="Escalator" --post_status=publish
- Use WP-CLI to create an
- Target Page:
- Create a page to host the form:
wp post create --post_type=page --post_title="Edit Me" --post_status=publish --post_content='[acf_frontend_form post_id="current_user" form_id="THE_FORM_ID"]'
- Create a page to host the form:
7. Expected Results
- Phase 2: The
admin_formmetadata should now containadministratorin therole_optionslist. - Phase 3: The response should indicate a successful update (HTTP 200 or a redirect).
- The Editor user's role in the database should change from
editortoadministrator.
8. Verification Steps
- Check User Role:
wp user get <attacker_user_id> --field=roles - Confirm Admin Access: Use the attacker's cookies to request
/wp-admin/settings-general.php. A successful response (200 OK) confirms administrative access. - Inspect Form Meta:
wp post primary-meta get <form_id> role_options(to confirm the bypass worked).
9. Alternative Approaches
- Direct Meta Update: If the Editor can update any post meta (due to ACF Frontend permissions), they might be able to update their own
wp_capabilitiesmeta directly via a generic "Edit Post" form if not properly restricted. - REST API: Check if
wp-json/acf-frontend/v1/formsendpoints exist and allow form configuration updates without proper capability checks on therole_optionsfield. - Pre-existing Admin Form: If the site already has an "Edit User" form for staff, an Editor might just be able to use it if
role_optionswasn't strictly defined, or if they can modify the existing form's options.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.