← Back to Feed CACHED · 2026-10-07 00:03:50 · CACHE_KEY CVE-2026-4986
CVE-2026-4986 · CWE-862 · Disclosed 2026-06-09

WPForms PayPal Commerce Webhook Forgery via Missing Signature Verification

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Leaving the cash register unattended in a store where anyone can walk in and stamp their own receipt "PAID"

CVE-2026-4986 affects WPForms (Lite and Pro) versions 1.10.0.1 through 1.10.0.4 — specifically sites that enabled the PayPal Commerce payment integration introduced in 1.10.0. The plugin registers a public REST endpoint at /wp-json/wpforms/ppc/webhooks/ with permission_callback => '__return_true' and processes incoming JSON payloads as PayPal events *without verifying the Paypal-Transmission-Sig header or performing any server-to-server callback*. An unauthenticated attacker can POST a forged PAYMENT.CAPTURE.COMPLETED or PAYMENT.CAPTURE.DENIED event to flip the payment state of any matching transaction record. The fix in 1.10.0.5 (released May 12, 2026) adds signature verification before dispatching events.

The vendor's MEDIUM / 5.3 score is honest and defensible. The CVSS vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N accurately captures the attack surface: unauthenticated, network-accessible, zero-click — but the ceiling is integrity-only with no confidentiality breach, no code execution, and no availability impact. The real-world harm is financial fraud on individual WordPress sites (marking unpaid orders as paid, or denying legitimate payments), not lateral movement or fleet compromise. Eleven independent researchers found the same bug, the PoC is a single curl command, and the install base is ~6 million — but only the subset running PayPal Commerce is actually vulnerable. The vendor called it right.

"Trivially forgeable PayPal webhooks let attackers mark transactions paid — but no RCE, no data theft."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Identify a vulnerable WPForms + PayPal Commerce target

The attacker scans for WordPress sites running WPForms versions 1.10.0.1–1.10.0.4 with PayPal Commerce enabled. The webhook endpoint /wp-json/wpforms/ppc/webhooks/ is publicly enumerable — a 200 or 405 response confirms the route is registered. No authentication or prior access is required.
Conditions required:
  • Target site runs WordPress with WPForms 1.10.0.1–1.10.0.4
  • PayPal Commerce addon is enabled and configured
Where this breaks in practice:
  • Only a subset of WPForms' 6M installs actually enable PayPal Commerce — most use it for simple contact forms
  • Sites on managed WordPress hosts may have WAF rules blocking unexpected REST API POSTs
Detection/coverage: WordPress REST API route enumeration is detectable via web server access logs. WAFs with WordPress-specific rulesets (Wordfence, Sucuri, Cloudflare WordPress rules) may flag anomalous POST traffic to plugin REST endpoints.
STEP 02

Craft a forged PayPal webhook event

The attacker constructs a JSON payload mimicking PayPal's webhook event structure. The key fields are event_type (e.g., PAYMENT.CAPTURE.COMPLETED) and resource.id (a transaction identifier). No PayPal-Transmission-Sig, Paypal-Transmission-Id, or other signature headers are required because the plugin never checks them. The PoC is a single curl -X POST command.
Conditions required:
  • Knowledge of PayPal webhook event schema (publicly documented by PayPal)
Where this breaks in practice:
  • None — the payload format is trivially available in PayPal's developer documentation
STEP 03

Submit forged event to the unprotected endpoint

The attacker POSTs the unsigned JSON to https://target/wp-json/wpforms/ppc/webhooks/. The handler accepts the body, decodes JSON, and dispatches it to the payment state machine without any sender verification. The forged event is processed as if it came from PayPal's infrastructure.
Conditions required:
  • HTTP POST access to the target site (internet-facing WordPress)
Where this breaks in practice:
  • Rate limiting or IP-based blocks on the REST API could slow automated attacks
  • Some CDN/WAF configurations strip or reject requests missing expected PayPal source IPs
Detection/coverage: Web server logs will show POST requests to the webhook path from non-PayPal IP ranges. PayPal's documented webhook source IPs (ipn.paypal.com ranges) can be used as a detection heuristic.
STEP 04

Payment state is manipulated

The handler updates the WPForms payment record to match the forged event. A PAYMENT.CAPTURE.COMPLETED event marks a pending transaction as paid, potentially triggering downstream fulfillment actions (email confirmations, access grants, order processing). A PAYMENT.CAPTURE.DENIED event can cancel legitimate payments. The attacker achieves financial fraud bounded to the site's WPForms payment workflow — but gains no code execution, no database access beyond payment states, and no ability to pivot laterally.
Conditions required:
  • The forged resource.id must match or be accepted by the handler's lookup logic
Where this breaks in practice:
  • If the handler does strict transaction ID matching, the attacker needs a valid pending transaction ID — blind spraying may produce mostly misses
  • The gap between WordPress payment records and PayPal's actual ledger creates reconciliation discrepancies that merchants can detect
Detection/coverage: Discrepancies between WPForms payment records and PayPal's merchant dashboard are the primary detection signal. WPForms logs (if enabled) may record state transitions without corresponding PayPal webhook signature validation.
03 · Compensating Control

1
MEDIUM 5.3→LOW 2.5
SEVERITY REDUCED
Restrict the webhook endpoint to PayPal source IPs — Add a server-level (nginx/Apache) or WAF IP allowlist on /wp-json/wpforms/ppc/webhooks/ to only accept POSTs from PayPal's documented webhook IP ranges. This breaks the attack chain at step 3 by preventing unauthorized sources from reaching the handler. No noisgate mitigation SLA applies for MEDIUM — go straight to the 365-day remediation window, but this quick server config change can be deployed immediately as defense-in-depth.
2
MEDIUM 5.3→IGNORE 0.0
SEVERITY REDUCED
Update WPForms to 1.10.0.5 or later — The definitive fix. Version 1.10.0.5 adds cryptographic signature verification before processing any webhook event. Deploy via WordPress auto-update or manual plugin update within the noisgate remediation SLA of 365 days for MEDIUM severity. Given the trivial exploit, earlier is better.
3
MEDIUM 5.3→MEDIUM 4.5
Enable PayPal IPN reconciliation and monitor for discrepancies — Configure PayPal's Instant Payment Notification (IPN) as a secondary verification channel, and set up alerts for payment state mismatches between WPForms records and PayPal's merchant dashboard. This doesn't prevent the attack but provides a detection and recovery mechanism for forged transactions.
4
MEDIUM 5.3→MEDIUM 4.0
Deploy a WordPress WAF plugin with REST API hardening — Plugins like Wordfence or Sucuri can apply rate limiting, geo-blocking, and anomaly detection to REST API endpoints. This adds friction to automated exploitation but does not fully prevent crafted single requests. Useful as a layer but not a substitute for patching.
What doesn't work
  • WordPress user role restrictions — the endpoint uses permission_callback => '__return_true', so WordPress authentication and capability checks are bypassed by design. Tightening user roles has zero effect.
  • Disabling XML-RPC — this is a REST API endpoint, not XML-RPC. Disabling XML-RPC provides no protection.
  • CAPTCHA or anti-bot on forms — the webhook endpoint is a server-to-server callback path, not a user-facing form. CAPTCHA does not apply.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo evidence. Not listed on CISA KEV. No GreyNoise tags or Shodan honeypot data observed for this endpoint. No known campaigns targeting WPForms PayPal webhooks as of October 2026.
Proof-of-ConceptPublic and trivial. A single curl command suffices: curl -X POST 'https://TARGET/wp-json/wpforms/ppc/webhooks/' -H 'Content-Type: application/json' -d '{"event_type":"PAYMENT.CAPTURE.COMPLETED","resource":{"id":"TXNID"}}'. Documented in the researcher's blog post. Not indexed on pocindex.io or major PoC aggregators as of this writing. No Metasploit or Nuclei template found.
EPSS0.0033 (bottom ~15th percentile) — indicates very low predicted exploitation probability in the next 30 days.
KEV StatusNot listed. No CISA KEV entry as of 2026-10-07.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N — Network-accessible, low complexity, no privileges, no interaction. Impact limited to low integrity. No confidentiality or availability impact.
Affected VersionsWPForms 1.10.0.1 through 1.10.0.4 (Lite and Pro). PayPal Commerce feature was introduced in 1.10.0. Versions prior to 1.10.0 are *not affected* (no PayPal Commerce endpoint).
Fixed Version1.10.0.5 (released May 12, 2026). Adds verify_webhook_signature() check before event dispatch. Auto-update available via WordPress plugin updater.
Install Base / ExposureWPForms has 6 million+ active installations across Lite and Pro. However, only sites that (a) upgraded to 1.10.0+ AND (b) enabled PayPal Commerce are vulnerable. PayPal Commerce is a premium/addon feature — the exposed population is a fraction of the total base.
Disclosure Date2026-05-19 (publicly published by WPScan). Fix released 2026-05-12 (patch preceded public disclosure).
ResearcherSudhanshu Chauhan (RedHunt Labs). Notably, 11 independent researchers reported the same bug, indicating the flaw was easily discoverable. Blog writeup by Himanshu Anand (reporter #11).

Sources.

  1. WPScan Advisory
  2. NVD Entry
  3. Researcher Blog — Himanshu Anand (Reporter #11)
  4. SentinelOne Vulnerability Database
  5. OpenCVE Details
  6. Strix.ai Advisory
  7. WPForms PayPal Commerce Addon Docs
  8. Vulnerability.circl.lu
05 · The Call

Final Verdict
= UNCHANGED to MEDIUM (5.3/10)

Why this verdict

  • Trivially exploitable, but impact-capped. The attack is unauthenticated, zero-click, and requires only a curl command — there is essentially zero friction to *reach* the endpoint. However, the impact ceiling is integrity-only: payment state manipulation. No code execution, no data exfiltration, no privilege escalation. This justifies the vendor's MEDIUM bucket.
  • Role multiplier: WPForms is a WordPress form plugin, not a high-value-role component. It is not an identity provider, hypervisor, CI/CD system, PAM, backup platform, database engine, security agent, or network edge appliance. The blast radius of successful exploitation is per-site financial records — not domain, fleet, or supply-chain scale. Even on an e-commerce WordPress site (the worst plausible role), the outcome is payment fraud bounded to one merchant's WPForms transactions, not lateral movement. No high-value-role floor applies.
  • Exposure narrowing. The 6M install base is the theoretical maximum. The actually-vulnerable population is the subset that (a) upgraded to 1.10.0+ and (b) activated PayPal Commerce — likely a single-digit percentage of total installs. This narrows the real-world target surface significantly but doesn't warrant a score adjustment because the remaining population is still large in absolute terms.
  • No exploitation signal. EPSS is 0.0033, no KEV listing, no GreyNoise/Shodan data, no known campaigns. Eleven researchers found it independently (indicating discoverability), but none reported active exploitation. This supports keeping the score where it is rather than upgrading.

Why not higher?

The impact is strictly integrity-only with no path to code execution, data exfiltration, or lateral movement. The CVSS vector's C:N/I:L/A:N accurately reflects the ceiling. WPForms is not a high-value-role component — even in the worst case (e-commerce site), successful exploitation yields per-site payment fraud, not domain takeover or fleet compromise. There is no deployment role that would trigger a HIGH or CRITICAL floor.

Why not lower?

The exploit is unauthenticated, network-accessible, requires no user interaction, and the PoC is a single curl command — the lowest possible friction. The financial fraud potential is real and actionable: an attacker can mark their own unpaid order as completed and receive goods or services. With 6M+ installs, even a small fraction using PayPal Commerce represents tens of thousands of targets. Dropping below MEDIUM would understate the ease of exploitation and the tangible financial harm.

06 · Verification

Crowdsourced verification payload.

Run this script on the target WordPress host (or any machine with HTTP access to the target). It checks the installed WPForms version via the plugin's readme.txt. Requires curl and grep. Usage: bash check_cve_2026_4986.sh https://example.com

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-4986 checker — WPForms PayPal webhook forgery
# Usage: bash check_cve_2026_4986.sh <wordpress_url>
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

TARGET="${1:-}"
if [ -z "$TARGET" ]; then
  echo "Usage: $0 <wordpress_url>"
  exit 2
fi

# Strip trailing slash
TARGET="${TARGET%/}"

# Try both plugin slugs (lite and pro)
VERSION=""
for SLUG in wpforms-lite wpforms; do
  RESPONSE=$(curl -sf "${TARGET}/wp-content/plugins/${SLUG}/readme.txt" 2>/dev/null || true)
  if [ -n "$RESPONSE" ]; then
    VERSION=$(echo "$RESPONSE" | grep -i '^Stable tag:' | head -1 | sed 's/[Ss]table [Tt]ag:[[:space:]]*//' | tr -d '[:space:]')
    break
  fi
done

if [ -z "$VERSION" ]; then
  echo "UNKNOWN — Could not detect WPForms version at ${TARGET}"
  echo "The plugin may not be installed, or readme.txt is not publicly accessible."
  exit 2
fi

echo "Detected WPForms version: ${VERSION}"

# Version comparison: vulnerable if < 1.10.0.5
# Split version into components
IFS='.' read -ra PARTS <<< "$VERSION"
MAJOR=${PARTS[0]:-0}
MINOR=${PARTS[1]:-0}
PATCH=${PARTS[2]:-0}
SUB=${PARTS[3]:-0}

# PayPal Commerce introduced in 1.10.0 — versions before 1.10.0 are not affected
if [ "$MAJOR" -lt 1 ] || ([ "$MAJOR" -eq 1 ] && [ "$MINOR" -lt 10 ]); then
  echo "PATCHED — Version ${VERSION} predates PayPal Commerce feature (introduced in 1.10.0). Not affected by CVE-2026-4986."
  exit 0
fi

# Vulnerable: 1.10.0.1 through 1.10.0.4
if [ "$MAJOR" -eq 1 ] && [ "$MINOR" -eq 10 ] && [ "$PATCH" -eq 0 ] && [ "$SUB" -lt 5 ]; then
  echo "VULNERABLE — WPForms ${VERSION} is affected by CVE-2026-4986 (PayPal webhook forgery). Update to 1.10.0.5+."
  exit 1
fi

echo "PATCHED — WPForms ${VERSION} is >= 1.10.0.5. CVE-2026-4986 is fixed."
exit 0