CVE-2025-7221
Executive Summary
CVE-2025-7221 is a Missing Authorization vulnerability in the GiveWP – Donation Plugin and Fundraising Platform for WordPress, affecting all versions up to and including 4.5.0. The flaw resides in the give_update_payment_status() function, which lacks a capability check, allowing authenticated attackers with GiveWP Worker-level access or higher to arbitrarily update donation statuses. This unauthorized modification can disrupt donation records, potentially leading to financial reporting inaccuracies and loss of donor trust. The vulnerability is classified as Medium Severity (CVSS 4.3) due to the requirement of authenticated access and the limited impact on data integrity. No public exploit code or proof-of-concept is currently available, and the vendor has not released a patch.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects a WordPress plugin distributed via the official WordPress plugin repository. Users are advised to monitor the plugin's update channel and apply any security patches immediately upon release. As a supply chain risk, organizations using GiveWP should verify the integrity of their plugin installation and consider temporary workarounds until a patch is available.
CVSS Breakdown & Threat Level
- CVSS Score: 4.3 (Medium)
- Vector: 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 (GiveWP Worker-level access)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: None
- Integrity Impact: Low
- Availability Impact: None
Threat Level: Medium. Exploitation requires authenticated access with a specific role, limiting the attack surface to internal or compromised users. The impact is confined to data integrity, with no direct data breach or service disruption.
Deep Dive & Mechanics
The vulnerability exists in the give_update_payment_status() function, which is intended to update the status of a donation (e.g., from "pending" to "completed"). The function is exposed via AJAX or REST API endpoints but lacks a proper capability check to verify that the requesting user has the necessary permissions to modify donation statuses.
Root Cause: The function does not call current_user_can() or any equivalent authorization check before processing the status update. This allows any authenticated user with the give_worker role (or higher) to invoke the function and change the status of any donation, regardless of their intended permissions.
Attack Scenario:
- An attacker gains authenticated access to a WordPress site with a GiveWP Worker account (or higher).
- The attacker crafts a request to the vulnerable endpoint, specifying a donation ID and a new status (e.g., "completed").
- The function processes the request without verifying the user's capability, updating the donation status.
- This can be used to mark donations as completed without actual payment, or to revert completed donations to pending, causing financial record discrepancies.
Vulnerable vs. Patched Code
Vulnerable Code (give_update_payment_status() in givewp/includes/payments/class-payment.php):
function give_update_payment_status( $payment_id, $status = 'publish' ) {
// No capability check
$payment = new Give_Payment( $payment_id );
$payment->update_status( $status );
return true;
}
Patched Code (Hypothetical fix):
function give_update_payment_status( $payment_id, $status = 'publish' ) {
// Add capability check
if ( ! current_user_can( 'edit_give_payments' ) ) {
return new WP_Error( 'unauthorized', __( 'You do not have permission to update payment status.', 'give' ) );
}
$payment = new Give_Payment( $payment_id );
$payment->update_status( $status );
return true;
}
The patched version introduces a capability check using current_user_can() with a specific capability like edit_give_payments, ensuring only authorized users can modify donation statuses.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A WordPress instance with GiveWP plugin version <= 4.5.0.
- Authenticated session with a user having the
give_workerrole.
Exploitation Steps:
- Log in to WordPress as a GiveWP Worker.
- Identify the AJAX action or REST endpoint for updating payment status. Typically, this is
give_update_payment_statusviaadmin-ajax.php. - Craft a POST request to update a donation status:
curl -X POST \
'http://target.com/wp-admin/admin-ajax.php' \
-H 'Cookie: wordpress_logged_in_<hash>=<session_cookie>' \
-d 'action=give_update_payment_status&payment_id=123&status=completed'
- Verify the status change by checking the donation record in the WordPress admin panel.
Note: No public exploit code is available; this is a conceptual demonstration.
Blue Team
Detection & Prevention:
- Monitor for unusual AJAX requests to
admin-ajax.phpwith thegive_update_payment_statusaction from low-privileged users. - Implement Web Application Firewall (WAF) rules to block requests to this endpoint from non-admin users.
- Restrict the
give_workerrole to only trusted users and audit its usage. - Apply the principle of least privilege: ensure GiveWP Worker accounts have minimal necessary permissions.
Honeypot:
- Create a fake donation record and monitor for unauthorized status changes to detect exploitation attempts.
Indicators of Compromise (IOCs)
- Log Entries: WordPress debug logs showing
give_update_payment_statuscalls from unexpected user roles. - Database Changes: Unusual donation status transitions (e.g., pending to completed without corresponding payment gateway confirmation).
- Network Traffic: POST requests to
/wp-admin/admin-ajax.phpwith parametersaction=give_update_payment_statusandpayment_id=<id>. - User Activity: Accounts with
give_workerrole making AJAX requests to update payment statuses.
Detection Engineering
YARA Rule
rule CVE_2025_7221_GiveWP_Missing_Auth {
meta:
description = "Detects GiveWP plugin files with missing capability check in give_update_payment_status"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-7221"
strings:
$func = "function give_update_payment_status" nocase
$no_check = "current_user_can" nocase
condition:
$func and not $no_check
}
Sigma Rule
title: CVE-2025-7221 GiveWP Unauthorized Payment Status Update
id: 8a9b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d
status: experimental
description: Detects attempts to exploit missing authorization in GiveWP plugin
author: Valters IT
logsource:
category: webserver
product: apache
service: access_combined
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'action=give_update_payment_status'
cs-uri-query|contains: 'payment_id='
condition: selection
falsepositives:
- Legitimate admin actions
level: medium
Suricata Rule
alert http any any -> any any (
msg:"CVE-2025-7221 GiveWP Unauthorized Payment Status Update";
flow:to_server,established;
content:"POST"; http_method;
content:"/wp-admin/admin-ajax.php"; http_uri;
content:"action=give_update_payment_status"; http_client_body;
content:"payment_id="; http_client_body;
sid:1000001;
rev:1;
reference:cve,2025-7221;
classtype:attempted-admin;
priority:2;
)
Remediation & Mitigation
Immediate Actions:
- Disable the GiveWP plugin if not critical to operations, until a patch is released.
- Restrict the
give_workerrole to only trusted users and monitor its activity. - Implement a WAF rule to block requests to
admin-ajax.phpwithaction=give_update_payment_statusfrom non-admin IPs.
Long-term Fix:
- Apply the vendor patch once released. If unavailable, manually add a capability check to the
give_update_payment_status()function as shown in the patched code example. - Regularly update the GiveWP plugin to the latest version.
- Conduct a security audit of all WordPress plugins and themes.
Workaround:
- Use a custom plugin or theme functions file to override the vulnerable function and add the missing capability check.
Valters IT
Securing Digital Frontiers
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.