
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-33661 is an authentication bypass vulnerability in the yansongda/pay PHP payment SDK that allows unauthenticated attackers to forge WeChat Pay callback notifications by manipulating the HTTP Host header. The verify_wechat_sign() function in src/Functions.php unconditionally skips RSA signature verification when the PSR-7 request's host resolves to localhost, a value fully controlled by the attacker via the Host HTTP header. The same bypass also affects verify_paypal_webhook_sign() and verify_stripe_webhook_sign() in the same library. All versions up to and including 3.7.19 are affected; version 3.7.20 contains the fix. The GitHub Advisory Database rates this High (CVSS v3.1 score 7.5 per NVD/Feedly; the vendor's own advisory scores it Moderate at 5.3) (GitHub Advisory, Security Advisory).
The root cause is CWE-290 (Authentication Bypass by Spoofing): the library contains a hardcoded development shortcut that skips all cryptographic verification when the request host equals localhost (GitHub Advisory). In PSR-7 implementations such as Nyholm and Guzzle PSR-7, $request->getUri()->getHost() reads directly from the attacker-supplied Host HTTP header, making the bypass trivially exploitable over the network with no privileges required. The vulnerable code block in src/Functions.php (lines 243–246 pre-patch) is:
if ($message instanceof ServerRequestInterface && 'localhost' === $message->getUri()->getHost()) {
return; // No signature verified!
}The fix (commit 26987eb) removes this conditional entirely, ensuring openssl_verify() is always called (Patch Commit).
Successful exploitation enables payment fraud: an attacker can send a crafted HTTP POST to a merchant's WeChat Pay (or PayPal/Stripe) callback endpoint with a forged Host: localhost header and a fabricated TRANSACTION.SUCCESS payload, causing the application to mark orders as paid without any actual payment being made (GitHub Advisory). The integrity impact is high — order and payment state can be manipulated — while confidentiality and availability are unaffected. Real-world exposure is partially mitigated in environments where Nginx, Ingress controllers, Cloudflare, or WAFs strip or reject non-canonical Host headers before the request reaches the application (Security Advisory).
A public proof-of-concept exploit (a single curl command) is included in the official security advisory and requires no authentication, special tools, or prior access (Security Advisory). The EPSS score is approximately 0.017% (4th percentile), indicating low current exploitation probability. There is no evidence of in-the-wild exploitation or threat actor attribution at this time, and the vulnerability is not listed in the CISA KEV catalog (GitHub Advisory).
yansongda/pay ≤ 3.7.19 with an exposed WeChat Pay callback endpoint (e.g., /payment/wechat/callback).Host header set to localhost to trigger the bypass condition in verify_wechat_sign().Wechatpay-Serial, Wechatpay-Timestamp, Wechatpay-Nonce, and Wechatpay-Signature headers — their values are irrelevant since verification is skipped.curl -X POST https://merchant.example.com/payment/wechat/callback \
-H "Host: localhost" \
-H "Content-Type: application/json" \
-H "Wechatpay-Serial: any" \
-H "Wechatpay-Timestamp: 1234567890" \
-H "Wechatpay-Nonce: abc" \
-H "Wechatpay-Signature: AAAA" \
-d '{"id":"fake-order","event_type":"TRANSACTION.SUCCESS"}'verify_wechat_sign() returns immediately without RSA verification; the application processes the fake notification and marks the order as paid (Security Advisory).Host: localhost header while the actual destination IP/domain is a public-facing server; requests with arbitrary or obviously invalid Wechatpay-Signature values (e.g., single characters like AAAA)./payment/wechat/callback) with Host: localhost from external IP addresses; application logs recording successful payment callback processing for orders with no corresponding upstream payment record.Upgrade yansongda/pay to version 3.7.20 or later, which removes the localhost bypass from verify_wechat_sign(), verify_paypal_webhook_sign(), and verify_stripe_webhook_sign() (Release v3.7.20, Patch Commit). As a temporary workaround, configure Nginx, a WAF, or an API gateway to reject or rewrite requests where the Host header does not match the expected merchant domain before they reach the application. Additionally, implement independent server-side order verification against the WeChat Pay API to confirm payment status rather than relying solely on callback data (GitHub Advisory).
The vulnerability received coverage from The Hacker Wire and Yazoul security advisory sites shortly after disclosure (The Hacker Wire, Yazoul Advisory). Community reaction has been measured; the advisory itself notes that most production environments using Nginx, Cloudflare, or WAFs are naturally protected, which has tempered alarm. The fix was released the same day as the advisory (March 23, 2026), limiting the window of exposure (Release v3.7.20).
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."