An unlocked mailbox on your checkout page that anyone can stuff with fake 'payment received' notes
WPForms' PayPal Standard/Commerce integration exposes a webhook endpoint that accepts incoming payment event notifications (e.g., PAYMENT.SALE.COMPLETED) but never validates the PayPal-Transmission-Sig header, PAYPAL-CERT-URL, or webhook ID against PayPal's verification API. Any unauthenticated actor who knows or guesses the site's webhook URL can POST a forged JSON body and mark an arbitrary form submission / order as paid, fulfilled, refunded, or cancelled. Affected: WPForms 1.10.0.1 through 1.10.0.4 (Lite and Pro paths that ship the PayPal addon). Fixed in 1.10.0.5.
Vendor rating of 5.3 MEDIUM / Integrity:Low is defensible on the raw CIA math — no confidentiality loss, no availability impact, integrity limited to payment-state records. But the *business* impact (fraudulent order fulfillment, refund abuse, subscription state flips) is worse than the CVSS suggests for the subset of sites using WPForms as a checkout. For the vast majority of WPForms installs (contact forms, lead capture, no payment addon enabled), the endpoint isn't reachable in a meaningful way and the CVE is inert. Net: MEDIUM is fair as a fleet-wide rating; sites actually taking money via WPForms+PayPal should treat this as HIGH for themselves.
5 steps from start to impact.
Identify a WPForms + PayPal target
wpscan, BuiltWith, or Wappalyzer surface WPForms; a checkout page containing a PayPal button confirms the addon is live. Mass-scanning via Shodan/urlscan for wp-content/plugins/wpforms filters candidates.- Target runs WordPress with WPForms 1.10.0.1–1.10.0.4
- PayPal addon activated on at least one form
- Webhook endpoint reachable from Internet
- Only a small fraction of the ~6M WPForms installs use the paid PayPal addon
- Cloudflare/WAF may hide plugin fingerprints
Locate the webhook endpoint
/?wpforms-listener=paypal or a REST namespace like /wp-json/wpforms/v1/paypal/webhook). The endpoint accepts POST without authentication because it's designed to receive PayPal's server-to-server calls.- Public HTTP(S) reachability
- Attacker can enumerate WordPress REST routes
- Some hosts restrict REST to logged-in users
- IP-allowlist of PayPal ranges (rare in WPForms deployments) blocks direct hits
Craft forged PayPal event
PAYMENT.SALE.COMPLETED or CHECKOUT.ORDER.APPROVED schema, referencing a custom_id or invoice value tied to a real pending form entry ID on the target. Because WPForms skips Paypal-Transmission-Sig and verify-webhook-signature API validation, the plugin trusts the body verbatim.- Knowledge of a valid pending entry / order ID (often sequential and enumerable)
- Knowledge of the PayPal webhook JSON schema (public)
- Guessing entry IDs may require some enumeration
- Some sites cross-check email/amount downstream
POST the forgery — cURL / Burp / custom script
curl -X POST to the webhook URL with Content-Type: application/json. No auth header, no signature required. WPForms parses the event and updates the linked entry's payment status to completed (or refunded, voided depending on event type).- No WAF rule blocking the POST
- No rate-limit on unauthenticated REST
- Rate-limited hosts drop repeated POSTs
- Some managed WP hosts (Kinsta, WPEngine) block unauthenticated REST writes
Realize business impact
- Downstream automation (fulfillment, license issuance, email drip) triggers on payment_status = completed
- Manual order review catches obvious anomalies
- Accounting reconciliation with PayPal ledger surfaces mismatches within 24-72h
The supporting signals.
| In-the-wild exploitation | No confirmed campaigns as of 2026-07-22. Not on CISA KEV. |
|---|---|
| Public PoC | WPScan advisory documents the forged-webhook technique; no weaponized public exploit repo, but the JSON payload is trivially reproducible from PayPal's own webhook docs. |
| EPSS | 0.00197 (~0.2%) — very low predicted 30-day exploitation likelihood. |
| KEV status | Not listed. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N — network, no auth, no user interaction, integrity-only impact rated Low. |
| Affected versions | WPForms 1.10.0.1 → 1.10.0.4 (PayPal addon required to be active). |
| Fixed version | 1.10.0.5 (released before 2026-06-09 disclosure). |
| Exposure population | WPForms is on ~6M WordPress sites per wordpress.org active-install data; only a *minority* run the PayPal addon (paid tier). Realistic exploitable population likely low tens of thousands globally. |
| Disclosure | Reported by Sudhanshu Chauhan (RedHunt Labs), coordinated by WPScan, published 2026-06-09. |
| CWE | CWE-862 Missing Authorization — specifically missing webhook signature verification (PayPal's verify-webhook-signature API not called). |
noisgate verdict.
The decisive factor is narrow exploitable population combined with integrity-only impact scoped to a single site's payment ledger: only WPForms installs with the PayPal addon actively wired to fulfillment automation are meaningfully at risk, and blast radius stops at that one site's orders — no cross-tenant, no code execution, no data exfil. That keeps this squarely in MEDIUM despite the unauthenticated network attack vector.
Why this verdict
- Unauthenticated + network reachable keeps this from being LOW — anyone on the Internet can hit the endpoint, no phishing or foothold required.
- Integrity-only, single-tenant blast radius caps it at MEDIUM — attacker can flip payment state on the target site but cannot read data, escalate on the host, or pivot to other WordPress sites.
- Role multiplier: WPForms is *not* in the high-value-role catalog. Even on an e-commerce site, the affected surface is one plugin's payment reconciliation table, not the identity, hypervisor, or CI plane. No fleet-scale outcome is plausible.
- Friction: PayPal addon required. The base WPForms plugin doesn't expose the vulnerable listener — the paid PayPal addon must be installed and activated. Most WPForms sites use it purely for contact/lead forms and are unaffected.
- Friction: business logic often catches it. Sites doing manual fulfillment, accounting reconciliation, or PayPal-dashboard cross-checks detect forged 'paid' states within days. Fully-automated dropship or digital-goods sites are the real victims.
- EPSS 0.2% and no KEV listing — no exploitation pressure driving an upgrade.
Why not higher?
HIGH would require either fleet-scale blast radius (this is per-site, integrity-only) or credible active exploitation (none reported, EPSS <1%). The bug can't be chained into RCE, credential theft, or lateral movement on the WordPress host — it terminates at a database field flip.
Why not lower?
LOW would ignore that the attack is unauthenticated, remotely reachable, trivial to weaponize from PayPal's public webhook schema, and directly monetizable on affected e-commerce sites. A site owner facing free-goods fraud does not experience this as LOW.
What to do — in priority order.
- Update WPForms to 1.10.0.5 or later — The definitive fix. Push through your WordPress patch pipeline within the noisgate MEDIUM 365-day window, but if you run WPForms + PayPal for real revenue, treat as HIGH for your own environment and deploy inside 30 days.
- WAF-block the webhook endpoint to PayPal IP ranges only — Add a Cloudflare / Wordfence / ModSecurity rule allowing POSTs to
/?wpforms-listener=paypaland the plugin's REST route ONLY from PayPal's published IPN/webhook egress ranges. Deploy same-day on money-taking sites as an interim gate. - Enable PayPal-side reconciliation job — Nightly cron: pull PayPal transaction ledger via API, diff against WPForms entries flagged
payment_status=completed, alert on any WPForms 'paid' entry with no matching PayPal transaction. Catches forgeries within 24h even on unpatched sites. - Disable auto-fulfillment on WPForms payment triggers — For high-risk workflows (digital downloads, license keys, shipping label generation), require manual approval or a second signal (e.g., Stripe order, PayPal API pull) before fulfillment until patched.
- MFA / 2FA on WordPress admin — the vulnerable endpoint is unauthenticated by design; admin MFA doesn't touch it.
- Fail2ban / login brute-force protections — the attack isn't a login, it's a single legitimate-looking POST.
- Generic 'update WordPress core' — this is a plugin CVE; core updates do nothing.
- Disabling xmlrpc.php — unrelated attack surface.
Crowdsourced verification payload.
Run this on the WordPress host (or via SSH to it) as any user with read access to wp-content/plugins/. Invoke as ./check-wpforms.sh /var/www/html where the argument is the WordPress docroot. No root required.
#!/usr/bin/env bash
# noisgate verifier for CVE-2026-4986 (WPForms PayPal webhook forgery)
# Usage: ./check-wpforms.sh <wordpress-docroot>
set -u
DOCROOT="${1:-/var/www/html}"
FIXED="1.10.0.5"
if [ ! -d "$DOCROOT" ]; then
echo "UNKNOWN: docroot $DOCROOT not found"
exit 2
fi
PLUGIN_FILE=$(find "$DOCROOT/wp-content/plugins" -maxdepth 3 -type f -name 'wpforms.php' 2>/dev/null | head -n1)
if [ -z "$PLUGIN_FILE" ]; then
# Lite variant
PLUGIN_FILE=$(find "$DOCROOT/wp-content/plugins" -maxdepth 3 -type f -name 'wpforms-lite.php' 2>/dev/null | head -n1)
fi
if [ -z "$PLUGIN_FILE" ]; then
echo "PATCHED: WPForms plugin not installed on this host"
exit 0
fi
VERSION=$(grep -iE '^\s*\*?\s*Version:' "$PLUGIN_FILE" | head -n1 | sed -E 's/.*Version:\s*([0-9.]+).*/\1/')
if [ -z "$VERSION" ]; then
echo "UNKNOWN: could not parse version from $PLUGIN_FILE"
exit 2
fi
# Check whether PayPal addon is active (increases real risk)
PAYPAL_ADDON=$(find "$DOCROOT/wp-content/plugins" -maxdepth 4 -type d -iname 'wpforms-paypal*' 2>/dev/null | head -n1)
# semver compare: vulnerable if 1.10.0.1 <= v < 1.10.0.5
awk_cmp() { awk -v v="$1" -v f="$2" 'BEGIN{split(v,a,"."); split(f,b,"."); for(i=1;i<=4;i++){x=a[i]+0;y=b[i]+0; if(x<y){print "lt";exit} else if(x>y){print "gt";exit}} print "eq"}'; }
LOWER=$(awk_cmp "$VERSION" "1.10.0.1")
UPPER=$(awk_cmp "$VERSION" "$FIXED")
if { [ "$LOWER" = "gt" ] || [ "$LOWER" = "eq" ]; } && [ "$UPPER" = "lt" ]; then
if [ -n "$PAYPAL_ADDON" ]; then
echo "VULNERABLE: WPForms $VERSION with PayPal addon active — CVE-2026-4986 exploitable"
exit 1
else
echo "VULNERABLE: WPForms $VERSION installed (PayPal addon not detected — bug present but not reachable). Patch anyway."
exit 1
fi
fi
echo "PATCHED: WPForms $VERSION (>= $FIXED or outside affected range)"
exit 0
If you remember one thing.
wpforms-paypal* present (the verifier script above), rank those first, and schedule the plugin update through your normal change window.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.