CVE-2026-96834 Claiming an email you do not own in GiveWP

Intrudify's autonomous pentesting engine discovered a sensitive data exposure in GiveWP, affecting all versions up to and including 4.16.9. Any Subscriber who owns a donor record can write an arbitrary list of additional email addresses onto it through the REST API, with no verification that they control those addresses. Because GiveWP resolves every donation to a donor by email, future guest donations under a claimed address are attached to the attacker.

Discovered by
Intrudify autonomous engine
Validated & reported by
Tudor Lasuschevici
Disclosure
24 September 2026
Severity
Medium · CVSS 6.5
Vulnerability class
Sensitive data exposure, CWE-862
Affected
GiveWP ≤ 4.16.9
Fixed in
4.17.0
Active installs
100,000+
Privilege required
Subscriber who has donated once
Data at risk
Donor name, address, amount, comment
Configuration
Default, no admin capability used

Summary

GiveWP is the most widely installed donation and fundraising plugin for WordPress. Intrudify's autonomous testing engine found that the donor record's additionalEmails field is writable by the donor themselves over REST, with no verification that they control the addresses and no check that an address already belongs to someone else.

That would be a data-integrity problem on its own. It becomes a disclosure because the donation pipeline resolves donors by email and consults exactly that field.

Technical detail

The write

On PATCH /wp-json/givewp/v3/donors/{id}, the only barrier for a non-admin is an ownership check: the donor's userId must match the current user. A Subscriber who has donated once passes it, because GiveWP sets that field on the donor record when a logged-in user donates.

The controller then applies every request field that is not explicitly non-editable. The non-editable list covers id, userId and createdAt. additionalEmails is in the schema with no readonly flag, so it is fully writable.

The repository deletes and re-inserts the donor's meta rows with no uniqueness or ownership check.

The asymmetry is the interesting part. The primary email column carries a database UNIQUE KEY, so a duplicate there is rejected by the schema itself. The additional-emails table has no such constraint. One lane is enforced by the database and the other is enforced by nothing, and both feed the same lookup.

Why the claim matters

Every donation runs through donor resolution. For a guest, there is no user id, so the lookup falls to email:

$donor = $userId ? Donor::whereUserId($userId) : null;   // null for a guest
if (!$donor) $donor = Donor::whereEmail($donorEmail);       // attacker-controlled

The repository checks the primary email column first, then falls back to matching additional emails, which returns the row the attacker forged. The guest's donation is attached to the attacker's donor rather than to a new record.

From attachment to disclosure

A listener appends the hijacked donation id to the attacker's donor payment ids. The receipt permission check grants a logged-in user the full receipt when the donation id appears in their own donor payment ids, so the attacker reads the unredacted receipt. The donation also lists in the attacker's own donor dashboard, whose permission gate is satisfied by any logged-in user owning a donor row.

Each of those three checks is correct in isolation. Each asks whether this donation belongs to this donor, and after the forged claim the answer is genuinely yes.

The chain

  1. The attacker registers as a Subscriber and makes one small donation, which creates a donor record they own.
  2. They obtain a REST nonce, which WordPress core issues to any logged-in user.
  3. One PATCH claims an arbitrary address on their own donor. The response echoes the stored value. No verification email is sent.
  4. A guest later donates under that address. Donor resolution matches the forged row and attaches the donation to the attacker.
  5. The attacker reads the donation, including the donor's real name, email and receipt details, from their own donor dashboard.

Verification and scope

We confirmed this on a clean installation of WordPress 7.1, PHP 8.3 and GiveWP 4.16.8.1 from the official package, using a stock Subscriber account whose admin menu shows only Profile and Donor. No administrative capability is used at any point in the chain.

CaseResult
PATCH additionalEmails as the owning SubscriberHTTP 200, stored
Donor lookup for the claimed addressreturns the attacker's donor
Address already a primary donor emailresolves to the real owner

That last row is the boundary, and we state it rather than claiming the stronger case. The vulnerability captures future first-time donations under an address that is not yet a primary donor email. It cannot retroactively steal an existing donor's records.

That still leaves a large practical surface. Most charity donations are one-off gifts from people who have never donated to that organisation before, which is precisely the population this affects. An attacker who can guess or enumerate likely donor addresses can claim them in advance and wait.

Impact

The exposed data is donor personally identifiable information and donation records: name, email address, postal address, amount given, and any comment left with the gift. On a recurring gift the subscription is tied to the attacker's donor as well.

The context matters here more than the severity score suggests. This is charitable giving, where the donor list itself is sensitive, donation amounts are personal, and the causes people support can reveal political affiliation, health status or religious belief. A disclosure of donor records is not equivalent to a disclosure of ordinary account data.

Remediation

Update GiveWP to 4.17.0 or later.

For maintainers, three changes are worth making together. Treat additional emails as non-writable by the donor over the self-service route, or gate them behind a verification email to the claimed address. Reject an address that already resolves to another donor, matching the constraint the primary email column already enforces. And add a uniqueness constraint at the database level so the rule holds regardless of which code path writes.

The wider lesson

There is no injection here, no missing nonce, and no capability check that fails. Every gate in the chain does what it was written to do. The vulnerability is that an identifier the system treats as proof of identity can be asserted rather than proven.

Email addresses are used as identity all over WordPress, and any feature that lets a user add one to their own record without verifying it converts a lookup key into a claim. The question worth asking of any such field is not whether writing it is authorised, but what else in the system resolves against it. Here the answer was the entire donation pipeline.

The database asymmetry is the detail an auditor should take away. The primary email column has a unique key and the meta table does not, so two code paths that feed the same lookup have completely different integrity guarantees. Where a constraint exists on one representation of a value and not another, the unconstrained one is where to look.

This is also the only finding in this research set whose consequence is purely a data disclosure rather than code execution or privilege escalation, and it is a useful reminder that the two are scored very differently while mattering similarly to the people whose data it is.

Disclosure timeline

  • 2026-09-16 Vulnerability identified and full chain validated by Intrudify, reported via Patchstack
  • 2026-09-24 Public disclosure · CVE-2026-96834 assigned

Questions

What is CVE-2026-96834?

CVE-2026-96834 is a sensitive data exposure vulnerability in the GiveWP WordPress plugin, versions 4.16.9 and earlier. It was discovered autonomously by the Intrudify AI penetration testing engine. A Subscriber can write an arbitrary list of additional emails onto their own donor record through the REST API with no verification of ownership, and GiveWP resolves incoming donations to a donor by matching those addresses.

What data does CVE-2026-96834 expose?

Future first-time guest donations made under a claimed address are attached to the attacker's donor record, so the attacker reads the full unredacted receipt including the donor's name, postal address, amount and comment, and sees the donation in their own donor dashboard.

How do I fix CVE-2026-96834?

Update GiveWP to version 4.17.0 or later. The underlying fix is to treat additional emails as non-writable by the donor themselves, or to require an ownership-verification step, and to reject an address that already resolves to another donor.

References

More advisories from Intrudify

Join the Future of
AI-Driven Pentesting