CVE-2026-75816: Unauthenticated user email changes in Frontend Admin for WordPress

Summary

CVE-2026-75816 is an authentication and authorization failure in Frontend Admin by DynamiApps, the WordPress plugin identified as acf-frontend-form-element. Under the form configuration described in the report, an unauthenticated visitor can cause an email field to be processed as a post update while the underlying record identifies a user. The resulting operation changes the selected account’s email address without checking permission to edit that user.

The report attributes a Critical rating and CVSS score of 9.8 to the NVD record, with Wordfence as the reporting source. That score is reproduced here, not independently calculated. The report classifies the issue as CWE-287. Its runtime evidence demonstrates an administrator email change on version 3.29.11, but does not demonstrate completed account takeover, remote code execution, or a service crash. This analysis relies on the supplied report and does not claim independent verification.

Root cause

The failure spans form visibility, record selection, action routing, and the email update hook. PermissionsTab::conditions_logic() allows a form to be displayed when who_can_see is set to all and applies the frontend_admin/special_permissions filter. Public visibility supplies the context for the attack, but does not establish permission to edit the record selected by the visitor.

For a form configured to obtain its edit target from a URL query parameter, get_form_fields() reads that value using sanitize_text_field() without requiring a numeric identifier. An ACF user record identifier beginning with user_ can therefore become the form’s post_id. Rendering also carries that target in the encrypted _acf_objects hidden field, which get_form_data() later restores into the post record. The reported chain relies on metadata supplied by the form itself; it does not require defeating that encryption.

ActionPost::conditions_logic() returns early for a nonnumeric post_id, before reaching current_user_can(‘edit_post’, $post_id). A user_-prefixed record target consequently avoids this authorization check. The submission handler is reachable through both authenticated and unauthenticated WordPress AJAX dispatch for frontend_admin/form_submit. Its nonce validation accepts a nonce obtainable from the public page, which does not establish the visitor’s authority to edit the target user.

A second routing failure makes the email field reachable through the post action. create_record() trusts submitted acff group names when constructing record fields. Grouping user_email under the post group routes it through ActionPost::run(), bypassing the ActionUser path that checks current_user_can(‘edit_user’). ActionPost::save_post() then passes non-core fields to acf_update_value(). The acf/pre_update_value/type=user_email filter reaches the user email field’s pre_update_value() method, which extracts the user identifier from the record prefix and calls wp_update_user(). In the examined 3.29.11 code, that email update has no capability or ownership check.

Attack path and prerequisites

Exposure requires the plugin to be installed and activated, with an existing frontend form accessible to unauthenticated visitors. The form must contain a user_email field and allow its edit target to come from the post_id URL parameter or another attacker-influenced post_id record value. The described configuration uses who_can_see=all and post_to_edit=url_query. Creating that public form administratively is a separate site configuration prerequisite, not a step an unauthenticated attacker is shown performing.

A visitor selects an ACF user record as the form’s edit target and obtains the rendered nonce and hidden record metadata. A subsequent submission to /wp-admin/admin-ajax.php uses the frontend_admin/form_submit action and places the email field under acff[post]. The nonnumeric target avoids the post authorization check, while the field grouping directs processing away from the user action. The email update hook then applies the replacement address to the selected user account.

The reported requests require no authenticated account, login cookie, or victim interaction. The direct impact is unauthenticated modification of an arbitrary user’s email address, including an administrator’s. This compromises account data integrity and can enable an attacker to pursue account takeover through the native WordPress password reset flow at /wp-login.php?action=lostpassword.

Completing that takeover additionally requires successful delivery of a reset email to the attacker-controlled replacement address. In the report, password reset reached account lookup and attempted delivery, but delivery failed. The cause was not investigated, and neither receipt of the reset email nor a final password change was demonstrated.

Affected scope

The report identifies versions through 3.29.12 as affected and 3.29.13 as fixed. Runtime evidence covers only 3.29.11 and cannot establish behavior across the entire reported range. The prevalence of the required public form configuration on real sites was not assessed, so exposure should not be assumed for every installation.

There is a material distinction between the reported affected range and the source comparison. According to that comparison, 3.29.12 adds current_user_can(‘edit_user’, $user_id) to the user_email update hook. The report concludes that this partial repair blocks the described unauthenticated chain, while leaving the nonnumeric ActionPost authorization shortcut in place. Version 3.29.12 nevertheless remains within the advisory range reproduced by the report.

The reported 3.29.13 changes limit legitimate nonnumeric ActionPost states to none and add_post; other nonnumeric values reach authorization checking and are reset to none. The source comparison also identifies a similar term action repair, numeric identifier handling in display.php::ajax_add_form(), and Role field ownership checks in submit.php. These are source-analysis findings, not runtime validation of either repaired version. Access challenges prevented the report from reading the Wordfence advisory and WordPress Trac changeset pages, so its fix analysis used official release archive comparisons rather than the unavailable original fix descriptions.

Detection and remediation

Upgrade to 3.29.13, the fixed version identified by the report. Review public frontend forms for the combination of anonymous access, a user_email field, and a visitor-controlled edit target. Restricting unauthenticated access to forms with that combination removes a prerequisite of the described attack while the upgrade is arranged.

Review available request records for public form access with a user_-prefixed post_id followed by frontend_admin/form_submit requests to /wp-admin/admin-ajax.php. Where request bodies are available, a user_email field grouped under acff[post] is a relevant indicator of the reported routing bypass. Correlate those requests with unexpected account email changes, particularly changes to administrator accounts.

The report identifies [FEA_PREVIEW_DEBUG] logging in 3.29.11 that can reveal a user_-prefixed post target with user_email stored under fields.post. Where such records already exist, they can corroborate the data flow. A successful “Post updated” response was observed, but submission success alone does not establish completed account takeover.

The report separately corroborated the email change through a changed email-derived SHA-256 hash in avatar_urls returned for the target user by the public /wp-json/wp/v2/users/ endpoint. This exposed an email-derived identifier to unauthenticated visitors and provided evidence beyond the submission response. It did not demonstrate reset email delivery or a password change.

References