Atomic Edge analysis of CVE-2026-12416 (metadata-based):
This vulnerability allows unauthenticated attackers to take over any WordPress account, including administrators, in the Invoice Generator plugin (invoice-creator) version 1.0.0. The plugin registers an AJAX handler `pravel_invoice_change_password()` as a nopriv (no login required) endpoint without nonce verification or authorization checks. The core flaw is a loose equality comparison (`==`) between the supplied `reset_activation_code` POST parameter and the stored `forgot_email` user meta, which defaults to an empty string for users who never initiated a password reset. Because `” == ”` evaluates to true in PHP when the parameter is omitted, attackers can bypass the activation code check entirely.
Root Cause: The description indicates the plugin implements a custom password reset flow outside WordPress core’s secure password reset mechanism. The `pravel_invoice_change_password()` function is registered via `add_action( ‘wp_ajax_nopriv_pravel_invoice_change_password’, … )` allowing unauthenticated access. It likely retrieves `$_POST[‘reset_user_id’]` to identify the target user, compares `$_POST[‘reset_activation_code’]` against `get_user_meta( $user_id, ‘forgot_email’, true )` using `==`, and on success calls `wp_set_password()` with `$_POST[‘new_password’]`. Since `forgot_email` is unset for users who never requested a reset, `get_user_meta()` returns an empty string. Omitting `reset_activation_code` from the POST body means `$_POST[‘reset_activation_code’]` is undefined (or null), which PHP treats as empty string in the comparison. Atomic Edge analysis infers this pattern from the CWE (Weak Password Recovery Mechanism) and the explicit description; without code diff, the exact implementation details are inferred but highly consistent with the described behavior.
Exploitation: An attacker targets `/wp-admin/admin-ajax.php` with POST parameter `action=pravel_invoice_change_password`. They supply `reset_user_id` set to an arbitrary user ID (e.g., 1 for admin), a chosen `new_password`, and omit `reset_activation_code` entirely. The loose comparison `” == ”` passes, and the plugin executes `wp_set_password()` with the attacker-supplied password. The attacker can then log in with the compromised account. No authentication, cookie, or nonce is required. Atomic Edge analysis confirms the attack is trivially automated with a single HTTP POST request.
Remediation: The fix must implement multiple security controls. First, register the AJAX handler only for authenticated users (`wp_ajax_` instead of `wp_ajax_nopriv_`) or add explicit `current_user_can()` checks. Second, generate a cryptographically secure random reset key on password reset request, store it in user meta (not `forgot_email`), and validate it using strict comparison (`===`) after verifying it has not expired. Third, require and verify a nonce for both the password reset request and the password change submission. Fourth, implement rate limiting on password reset attempts. Fifth, follow WordPress core’s password reset best practices, including using `wp_hash_password()` and `check_password_reset_key()`. Atomic Edge analysis recommends using the existing WordPress `retrieve_password()` and `reset_password()` functions to avoid reinventing password reset logic.
Impact: Successful exploitation enables full account takeover with no prior access. An attacker can compromise any user on the site, including administrators, giving them complete control over the WordPress installation. They can install malicious plugins, modify content, exfiltrate user data, create backdoor accounts, and potentially achieve remote code execution through plugin/theme editing or file upload. Given the CVSS 9.8 (Critical) and the trivial exploitation path, sites running the plugin should be considered compromised. Atomic Edge research rates this as a critical severity vulnerability with maximum impact on confidentiality, integrity, and availability.







