VYPR
High severity8.6NVD Advisory· Published Mar 26, 2026· Updated Apr 1, 2026

CVE-2026-33661

CVE-2026-33661

Description

Pay is an open-source payment SDK extension package for various Chinese payment services. Prior to version 3.7.20, 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. Version 3.7.20 fixes the issue.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
yansongda/payPackagist
< 3.7.203.7.20

Affected products

1
  • cpe:2.3:a:yansongda:pay:*:*:*:*:*:*:*:*
    Range: <3.7.20

Patches

1
26987ebf789f

fix: 修复 localhost 签名验证绕过漏洞 (GHSA-q938-ghwv-8gvc) (#1131)

https://github.com/yansongda/payCopilotMar 23, 2026via ghsa
12 files changed · +106 46
  • CHANGELOG.md+4 0 modified
    @@ -5,6 +5,10 @@
     - feat: 新增 PayPal 支付 (#1127)
     - feat: 新增 Stripe 支付 (#1130)
     
    +### fixed
    +
    +- fix: 修复 localhost 签名验证绕过漏洞 (GHSA-q938-ghwv-8gvc) (#1131)
    +
     ## v3.7.19
     
     ### added
    
  • src/Functions.php+0 12 modified
    @@ -247,10 +247,6 @@ function get_wechat_sign_v2(array $config, array $payload, bool $upper = true):
      */
     function verify_wechat_sign(ResponseInterface|ServerRequestInterface $message, array $params): void
     {
    -    if ($message instanceof ServerRequestInterface && 'localhost' === $message->getUri()->getHost()) {
    -        return;
    -    }
    -
         $wechatSerial = $message->getHeaderLine('Wechatpay-Serial');
         $timestamp = $message->getHeaderLine('Wechatpay-Timestamp');
         $random = $message->getHeaderLine('Wechatpay-Nonce');
    @@ -730,10 +726,6 @@ function get_paypal_access_token(array $params): string
      */
     function verify_paypal_webhook_sign(ServerRequestInterface $request, array $params): void
     {
    -    if ('localhost' === $request->getUri()->getHost()) {
    -        return;
    -    }
    -
         $config = get_provider_config('paypal', $params);
     
         $webhookId = $config['webhook_id'] ?? null;
    @@ -811,10 +803,6 @@ function get_stripe_url(array $config, ?Collection $payload): string
      */
     function verify_stripe_webhook_sign(ServerRequestInterface $request, array $params): void
     {
    -    if ('localhost' === $request->getUri()->getHost()) {
    -        return;
    -    }
    -
         $config = get_provider_config('stripe', $params);
         $webhookSecret = $config['webhook_secret'] ?? null;
     
    
  • tests/FunctionTest.php+2 14 modified
    @@ -247,7 +247,7 @@ public function testVerifyWechatSign()
                 200,
                 [
                     'Wechatpay-Nonce' => 'e59e78a6c3f7dfd7e84aabee71be0452',
    -                'Wechatpay-Signature' => 'Bb10ZUsON47E/qLjecjk6ESLt7obZCvCCAXAEoD1Q+K548fz9h6YBgR3PZzviTmjsA3/r22qEC3r/yelFAn4pl4rJBGqrjo4ODJkOPlaDnHZwYotDvf6RcASpKB9ExCb33hAijHCiMzr9V9skNrj5F9eXc96lNZN3R5MVLsTF97nV922JIzyCrZ668khYPrn1jl5pCBpYDQ3rskgmZ+nnjg7M9vRAfTowEydSEGtsKjXUSaaKui2RDUuX8ZwxVcBTRng978Gh9s4mdRxs+mlv3gP1xQHdpa0mYMG0yGzLcWOTgrkt27sAwFnuXj9WtlEAgz/1DYntujKPxilMVGRow==',
    +                'Wechatpay-Signature' => 'Ut3dG8cMx5W1lbSQhHay068F6khScuPQJM/Z9+suaaSkbYUspFRlkdp2VR/6w5UMvioN0EveSgfypQFVqmT6tI//cWrA1J9rlnKmZ+FgdCMqg7FQnpMRzc1Ap+3mZMtN9GrzYqp/UdgotX6HRfGL3hP8pG1YuijHNrL0QRS17bNYwZX8Mj3qLKUQRpqbfE+TC5yvzh1gEVPBFTwvZdZvXIQpjC/sB2QDSvo72CWgm4huh1h/kMzsrsO+wXXLqDfU01YX8aLbBrjvpcob50lc5XZ2WX5nBbpJXaRatIhBUmkR/ccrQhxWN7YqEobBGK/2DYhr6e6CvTgVdpZUUEcMFw==',
                     'Wechatpay-Timestamp' => '1626444144',
                     'Wechatpay-Serial' => '45F59D4DABF31918AFCEC556D5D2C6E376675D57',
                 ],
    @@ -256,15 +256,11 @@ public function testVerifyWechatSign()
             verify_wechat_sign($response, []);
             self::assertTrue(true);
     
    -        $serverRequest = new ServerRequest('POST', 'http://localhost');
    -        verify_wechat_sign($serverRequest, []);
    -        self::assertTrue(true);
    -
             $response = new Response(
                 200,
                 [
                     'Wechatpay-Nonce' => 'e59e78a6c3f7dfd7e84aabee71be0452',
    -                'Wechatpay-Signature' => 'Bb10ZUsON47E/qLjecjk6ESLt7obZCvCCAXAEoD1Q+K548fz9h6YBgR3PZzviTmjsA3/r22qEC3r/yelFAn4pl4rJBGqrjo4ODJkOPlaDnHZwYotDvf6RcASpKB9ExCb33hAijHCiMzr9V9skNrj5F9eXc96lNZN3R5MVLsTF97nV922JIzyCrZ668khYPrn1jl5pCBpYDQ3rskgmZ+nnjg7M9vRAfTowEydSEGtsKjXUSaaKui2RDUuX8ZwxVcBTRng978Gh9s4mdRxs+mlv3gP1xQHdpa0mYMG0yGzLcWOTgrkt27sAwFnuXj9WtlEAgz/1DYntujKPxilMVGRow==',
    +                'Wechatpay-Signature' => 'Ut3dG8cMx5W1lbSQhHay068F6khScuPQJM/Z9+suaaSkbYUspFRlkdp2VR/6w5UMvioN0EveSgfypQFVqmT6tI//cWrA1J9rlnKmZ+FgdCMqg7FQnpMRzc1Ap+3mZMtN9GrzYqp/UdgotX6HRfGL3hP8pG1YuijHNrL0QRS17bNYwZX8Mj3qLKUQRpqbfE+TC5yvzh1gEVPBFTwvZdZvXIQpjC/sB2QDSvo72CWgm4huh1h/kMzsrsO+wXXLqDfU01YX8aLbBrjvpcob50lc5XZ2WX5nBbpJXaRatIhBUmkR/ccrQhxWN7YqEobBGK/2DYhr6e6CvTgVdpZUUEcMFw==',
                     'Wechatpay-Timestamp' => '1626444144',
                     'Wechatpay-Serial' => '45F59D4DABF31918AFCEC556D5D2C6E376675D57',
                 ],
    @@ -768,14 +764,6 @@ public function testGetPaypalAccessTokenFresh()
             self::assertNotEmpty(Pay::get(ConfigInterface::class)->get('paypal.default._access_token_expiry'));
         }
     
    -    public function testVerifyPaypalWebhookSignLocalhost()
    -    {
    -        $request = new ServerRequest('POST', 'http://localhost', [], '{}');
    -
    -        verify_paypal_webhook_sign($request, []);
    -        self::assertTrue(true);
    -    }
    -
         public function testVerifyPaypalWebhookSignMissingWebhookId()
         {
             Pay::get(ConfigInterface::class)->set('paypal.default.webhook_id', '');
    
  • tests/Plugin/Paypal/V2/Pay/CallbackPluginTest.php+19 1 modified
    @@ -4,10 +4,15 @@
     
     namespace Yansongda\Pay\Tests\Plugin\Paypal\V2\Pay;
     
    +use GuzzleHttp\Client;
    +use GuzzleHttp\Psr7\Response;
     use GuzzleHttp\Psr7\ServerRequest;
    +use Mockery;
    +use Yansongda\Artful\Contract\HttpClientInterface;
     use Yansongda\Artful\Exception\InvalidParamsException;
     use Yansongda\Artful\Rocket;
     use Yansongda\Pay\Exception\Exception;
    +use Yansongda\Pay\Pay;
     use Yansongda\Pay\Plugin\Paypal\V2\Pay\CallbackPlugin;
     use Yansongda\Pay\Tests\TestCase;
     
    @@ -40,7 +45,20 @@ public function testNormalCallback()
                 'resource' => ['id' => 'ORDER_123', 'status' => 'APPROVED'],
             ]);
     
    -        $request = new ServerRequest('POST', 'http://localhost', [
    +        $tokenResponse = new Response(200, [], json_encode([
    +            'access_token' => 'test_token_123',
    +            'token_type' => 'Bearer',
    +            'expires_in' => 32400,
    +        ]));
    +        $verifyResponse = new Response(200, [], json_encode([
    +            'verification_status' => 'SUCCESS',
    +        ]));
    +
    +        $http = Mockery::mock(Client::class);
    +        $http->shouldReceive('sendRequest')->andReturn($tokenResponse, $verifyResponse);
    +        Pay::set(HttpClientInterface::class, $http);
    +
    +        $request = new ServerRequest('POST', 'https://pay.yansongda.cn/paypal/notify', [
                 'PAYPAL-TRANSMISSION-ID' => 'test-id',
                 'PAYPAL-TRANSMISSION-TIME' => '2024-01-01T00:00:00Z',
                 'PAYPAL-TRANSMISSION-SIG' => 'test-sig',
    
  • tests/Plugin/Stripe/V1/Pay/CallbackPluginTest.php+17 3 modified
    @@ -35,7 +35,15 @@ public function testMissingRequestThrowsException()
     
         public function testInvalidJsonBodyThrowsException()
         {
    -        $request = new ServerRequest('POST', 'http://localhost', [], 'not-valid-json');
    +        $body = 'not-valid-json';
    +        $timestamp = time();
    +        $webhookSecret = 'whsec_stripe_webhook_secret';
    +        $expectedSig = hash_hmac('sha256', $timestamp.'.'.$body, $webhookSecret);
    +        $signatureHeader = 't='.$timestamp.',v1='.$expectedSig;
    +
    +        $request = new ServerRequest('POST', 'https://pay.yansongda.cn/stripe/notify', [
    +            'Stripe-Signature' => $signatureHeader,
    +        ], $body);
     
             $rocket = new Rocket();
             $rocket->setParams(['_request' => $request, '_params' => []]);
    @@ -59,8 +67,14 @@ public function testNormalCallback()
                 ],
             ]);
     
    -        // localhost skips signature verification in CallbackPlugin
    -        $request = new ServerRequest('POST', 'http://localhost', [], $body);
    +        $timestamp = time();
    +        $webhookSecret = 'whsec_stripe_webhook_secret';
    +        $expectedSig = hash_hmac('sha256', $timestamp.'.'.$body, $webhookSecret);
    +        $signatureHeader = 't='.$timestamp.',v1='.$expectedSig;
    +
    +        $request = new ServerRequest('POST', 'https://pay.yansongda.cn/stripe/notify', [
    +            'Stripe-Signature' => $signatureHeader,
    +        ], $body);
     
             $rocket = new Rocket();
             $rocket->setParams(['_request' => $request, '_params' => []]);
    
  • tests/Plugin/Stripe/V1/VerifyWebhookSignTest.php+5 4 modified
    @@ -14,14 +14,15 @@
     
     class VerifyWebhookSignTest extends TestCase
     {
    -    public function testLocalhostSkipsVerification()
    +    public function testLocalhostNoLongerSkipsVerification()
         {
             $request = new ServerRequest('POST', 'http://localhost', [], '{}');
     
    -        // Should not throw — localhost always skips verification
    -        verify_stripe_webhook_sign($request, []);
    +        // localhost should no longer skip verification — missing Stripe-Signature should throw SIGN_EMPTY
    +        self::expectException(InvalidSignException::class);
    +        self::expectExceptionCode(Exception::SIGN_EMPTY);
     
    -        self::assertTrue(true);
    +        verify_stripe_webhook_sign($request, []);
         }
     
         public function testMissingWebhookSecretThrowsException()
    
  • tests/Plugin/Wechat/V3/CallbackPluginTest.php+2 2 modified
    @@ -23,10 +23,10 @@ public function testNormal()
         {
             $request = new ServerRequest(
                 'POST',
    -            'http://localhost',
    +            'https://pay.yansongda.cn/wechat/notify',
                 [
                     'Wechatpay-Nonce' => 'e59e78a6c3f7dfd7e84aabee71be0452',
    -                'Wechatpay-Signature' => 'Bb10ZUsON47E/qLjecjk6ESLt7obZCvCCAXAEoD1Q+K548fz9h6YBgR3PZzviTmjsA3/r22qEC3r/yelFAn4pl4rJBGqrjo4ODJkOPlaDnHZwYotDvf6RcASpKB9ExCb33hAijHCiMzr9V9skNrj5F9eXc96lNZN3R5MVLsTF97nV922JIzyCrZ668khYPrn1jl5pCBpYDQ3rskgmZ+nnjg7M9vRAfTowEydSEGtsKjXUSaaKui2RDUuX8ZwxVcBTRng978Gh9s4mdRxs+mlv3gP1xQHdpa0mYMG0yGzLcWOTgrkt27sAwFnuXj9WtlEAgz/1DYntujKPxilMVGRow==',
    +                'Wechatpay-Signature' => 'NmmOwkXg89J9UP9gnoGeGZUdSflYhOzD/Imxv0SZf09+42Yn+u8DHQs/QcsOtD1O9hi38PizLnyMQ7NyqkQqVZCu7ID532FOiKkU6qIhrrCrm8w5ktJTXUorH8gEQtxZSKJ0Z0I/fsOBhnvoBRRlIyvEwoESAcJuyJYCgQuvFaqGYDOjLW7umTdO0vUZnH9TJfxfziLxwEYoH09D43H+hXL4oKAF+aIdAiWyS/CwnE4BB8j4NGsCi4v4cAZkJjqV45koAtzXVBzYjccURNSRUYOZv9IW7CqOFmOWsmAN5bVncs4S89lMNW+UIqNRx4tpIrU4CuX81V0tVFcweKnqNQ==',
                     'Wechatpay-Timestamp' => '1626444144',
                     'Wechatpay-Serial' => '45F59D4DABF31918AFCEC556D5D2C6E376675D57',
                 ],
    
  • tests/Plugin/Wechat/V3/VerifySignaturePluginTest.php+1 1 modified
    @@ -38,7 +38,7 @@ public function testNormal()
                 200,
                 [
                     'Wechatpay-Nonce' => 'e59e78a6c3f7dfd7e84aabee71be0452',
    -                'Wechatpay-Signature' => 'Bb10ZUsON47E/qLjecjk6ESLt7obZCvCCAXAEoD1Q+K548fz9h6YBgR3PZzviTmjsA3/r22qEC3r/yelFAn4pl4rJBGqrjo4ODJkOPlaDnHZwYotDvf6RcASpKB9ExCb33hAijHCiMzr9V9skNrj5F9eXc96lNZN3R5MVLsTF97nV922JIzyCrZ668khYPrn1jl5pCBpYDQ3rskgmZ+nnjg7M9vRAfTowEydSEGtsKjXUSaaKui2RDUuX8ZwxVcBTRng978Gh9s4mdRxs+mlv3gP1xQHdpa0mYMG0yGzLcWOTgrkt27sAwFnuXj9WtlEAgz/1DYntujKPxilMVGRow==',
    +                'Wechatpay-Signature' => 'Ut3dG8cMx5W1lbSQhHay068F6khScuPQJM/Z9+suaaSkbYUspFRlkdp2VR/6w5UMvioN0EveSgfypQFVqmT6tI//cWrA1J9rlnKmZ+FgdCMqg7FQnpMRzc1Ap+3mZMtN9GrzYqp/UdgotX6HRfGL3hP8pG1YuijHNrL0QRS17bNYwZX8Mj3qLKUQRpqbfE+TC5yvzh1gEVPBFTwvZdZvXIQpjC/sB2QDSvo72CWgm4huh1h/kMzsrsO+wXXLqDfU01YX8aLbBrjvpcob50lc5XZ2WX5nBbpJXaRatIhBUmkR/ccrQhxWN7YqEobBGK/2DYhr6e6CvTgVdpZUUEcMFw==',
                     'Wechatpay-Timestamp' => '1626444144',
                     'Wechatpay-Serial' => '45F59D4DABF31918AFCEC556D5D2C6E376675D57',
                 ],
    
  • tests/Provider/PaypalTest.php+34 1 modified
    @@ -2,8 +2,12 @@
     
     namespace Yansongda\Pay\Tests\Provider;
     
    +use GuzzleHttp\Client;
    +use GuzzleHttp\Psr7\Response;
     use GuzzleHttp\Psr7\ServerRequest;
    +use Mockery;
     use Psr\Http\Message\ResponseInterface;
    +use Yansongda\Artful\Contract\HttpClientInterface;
     use Yansongda\Artful\Exception\Exception;
     use Yansongda\Artful\Exception\InvalidParamsException;
     use Yansongda\Artful\Plugin\AddPayloadBodyPlugin;
    @@ -70,7 +74,20 @@ public function testCallback()
                 'resource' => ['id' => 'ORDER_123', 'status' => 'APPROVED'],
             ]);
     
    -        $request = new ServerRequest('POST', 'http://localhost', [
    +        $tokenResponse = new Response(200, [], json_encode([
    +            'access_token' => 'test_token_123',
    +            'token_type' => 'Bearer',
    +            'expires_in' => 32400,
    +        ]));
    +        $verifyResponse = new Response(200, [], json_encode([
    +            'verification_status' => 'SUCCESS',
    +        ]));
    +
    +        $http = Mockery::mock(Client::class);
    +        $http->shouldReceive('sendRequest')->andReturn($tokenResponse, $verifyResponse);
    +        Pay::set(HttpClientInterface::class, $http);
    +
    +        $request = new ServerRequest('POST', 'https://pay.yansongda.cn/paypal/notify', [
                 'PAYPAL-TRANSMISSION-ID' => 'test-id',
                 'PAYPAL-TRANSMISSION-TIME' => '2024-01-01T00:00:00Z',
                 'PAYPAL-TRANSMISSION-SIG' => 'test-sig',
    @@ -92,10 +109,26 @@ public function testCallbackWithArray()
                 'resource' => ['id' => 'CAPTURE_456', 'status' => 'COMPLETED'],
             ]);
     
    +        $tokenResponse = new Response(200, [], json_encode([
    +            'access_token' => 'test_token_456',
    +            'token_type' => 'Bearer',
    +            'expires_in' => 32400,
    +        ]));
    +        $verifyResponse = new Response(200, [], json_encode([
    +            'verification_status' => 'SUCCESS',
    +        ]));
    +
    +        $http = Mockery::mock(Client::class);
    +        $http->shouldReceive('sendRequest')->andReturn($tokenResponse, $verifyResponse);
    +        Pay::set(HttpClientInterface::class, $http);
    +
             $result = Pay::paypal()->callback([
                 'headers' => [
                     'PAYPAL-TRANSMISSION-ID' => 'test-id',
    +                'PAYPAL-TRANSMISSION-TIME' => '2024-01-01T00:00:00Z',
                     'PAYPAL-TRANSMISSION-SIG' => 'test-sig',
    +                'PAYPAL-CERT-URL' => 'https://api.sandbox.paypal.com/v1/notifications/certs/CERT-123',
    +                'PAYPAL-AUTH-ALGO' => 'SHA256withRSA',
                 ],
                 'body' => $body,
             ]);
    
  • tests/Provider/StripeTest.php+14 3 modified
    @@ -60,8 +60,14 @@ public function testCallback()
                 ],
             ]);
     
    -        // localhost skips signature verification
    -        $request = new ServerRequest('POST', 'http://localhost', [], $body);
    +        $timestamp = time();
    +        $webhookSecret = 'whsec_stripe_webhook_secret';
    +        $expectedSig = hash_hmac('sha256', $timestamp.'.'.$body, $webhookSecret);
    +        $signatureHeader = 't='.$timestamp.',v1='.$expectedSig;
    +
    +        $request = new ServerRequest('POST', 'https://pay.yansongda.cn/stripe/notify', [
    +            'Stripe-Signature' => $signatureHeader,
    +        ], $body);
     
             $result = Pay::stripe()->callback($request);
     
    @@ -83,8 +89,13 @@ public function testCallbackWithArray()
                 ],
             ]);
     
    +        $timestamp = time();
    +        $webhookSecret = 'whsec_stripe_webhook_secret';
    +        $expectedSig = hash_hmac('sha256', $timestamp.'.'.$body, $webhookSecret);
    +        $signatureHeader = 't='.$timestamp.',v1='.$expectedSig;
    +
             $result = Pay::stripe()->callback([
    -            'headers' => ['Stripe-Signature' => 'test-sig'],
    +            'headers' => ['Stripe-Signature' => $signatureHeader],
                 'body' => $body,
             ]);
     
    
  • tests/Provider/WechatTest.php+4 4 modified
    @@ -58,7 +58,7 @@ public function testCancel()
                 200,
                 [
                     'Wechatpay-Nonce' => 'e59e78a6c3f7dfd7e84aabee71be0452',
    -                'Wechatpay-Signature' => 'Bb10ZUsON47E/qLjecjk6ESLt7obZCvCCAXAEoD1Q+K548fz9h6YBgR3PZzviTmjsA3/r22qEC3r/yelFAn4pl4rJBGqrjo4ODJkOPlaDnHZwYotDvf6RcASpKB9ExCb33hAijHCiMzr9V9skNrj5F9eXc96lNZN3R5MVLsTF97nV922JIzyCrZ668khYPrn1jl5pCBpYDQ3rskgmZ+nnjg7M9vRAfTowEydSEGtsKjXUSaaKui2RDUuX8ZwxVcBTRng978Gh9s4mdRxs+mlv3gP1xQHdpa0mYMG0yGzLcWOTgrkt27sAwFnuXj9WtlEAgz/1DYntujKPxilMVGRow==',
    +                'Wechatpay-Signature' => 'Ut3dG8cMx5W1lbSQhHay068F6khScuPQJM/Z9+suaaSkbYUspFRlkdp2VR/6w5UMvioN0EveSgfypQFVqmT6tI//cWrA1J9rlnKmZ+FgdCMqg7FQnpMRzc1Ap+3mZMtN9GrzYqp/UdgotX6HRfGL3hP8pG1YuijHNrL0QRS17bNYwZX8Mj3qLKUQRpqbfE+TC5yvzh1gEVPBFTwvZdZvXIQpjC/sB2QDSvo72CWgm4huh1h/kMzsrsO+wXXLqDfU01YX8aLbBrjvpcob50lc5XZ2WX5nBbpJXaRatIhBUmkR/ccrQhxWN7YqEobBGK/2DYhr6e6CvTgVdpZUUEcMFw==',
                     'Wechatpay-Timestamp' => '1626444144',
                     'Wechatpay-Serial' => '45F59D4DABF31918AFCEC556D5D2C6E376675D57',
                 ],
    @@ -98,7 +98,7 @@ public function testClose()
                 200,
                 [
                     'Wechatpay-Nonce' => 'e59e78a6c3f7dfd7e84aabee71be0452',
    -                'Wechatpay-Signature' => 'Bb10ZUsON47E/qLjecjk6ESLt7obZCvCCAXAEoD1Q+K548fz9h6YBgR3PZzviTmjsA3/r22qEC3r/yelFAn4pl4rJBGqrjo4ODJkOPlaDnHZwYotDvf6RcASpKB9ExCb33hAijHCiMzr9V9skNrj5F9eXc96lNZN3R5MVLsTF97nV922JIzyCrZ668khYPrn1jl5pCBpYDQ3rskgmZ+nnjg7M9vRAfTowEydSEGtsKjXUSaaKui2RDUuX8ZwxVcBTRng978Gh9s4mdRxs+mlv3gP1xQHdpa0mYMG0yGzLcWOTgrkt27sAwFnuXj9WtlEAgz/1DYntujKPxilMVGRow==',
    +                'Wechatpay-Signature' => 'Ut3dG8cMx5W1lbSQhHay068F6khScuPQJM/Z9+suaaSkbYUspFRlkdp2VR/6w5UMvioN0EveSgfypQFVqmT6tI//cWrA1J9rlnKmZ+FgdCMqg7FQnpMRzc1Ap+3mZMtN9GrzYqp/UdgotX6HRfGL3hP8pG1YuijHNrL0QRS17bNYwZX8Mj3qLKUQRpqbfE+TC5yvzh1gEVPBFTwvZdZvXIQpjC/sB2QDSvo72CWgm4huh1h/kMzsrsO+wXXLqDfU01YX8aLbBrjvpcob50lc5XZ2WX5nBbpJXaRatIhBUmkR/ccrQhxWN7YqEobBGK/2DYhr6e6CvTgVdpZUUEcMFw==',
                     'Wechatpay-Timestamp' => '1626444144',
                     'Wechatpay-Serial' => '45F59D4DABF31918AFCEC556D5D2C6E376675D57',
                 ],
    @@ -136,10 +136,10 @@ public function testCallback()
         {
             $request = new ServerRequest(
                 'POST',
    -            'http://localhost',
    +            'https://pay.yansongda.cn/wechat/notify',
                 [
                     'Wechatpay-Nonce' => 'e59e78a6c3f7dfd7e84aabee71be0452',
    -                'Wechatpay-Signature' => 'Bb10ZUsON47E/qLjecjk6ESLt7obZCvCCAXAEoD1Q+K548fz9h6YBgR3PZzviTmjsA3/r22qEC3r/yelFAn4pl4rJBGqrjo4ODJkOPlaDnHZwYotDvf6RcASpKB9ExCb33hAijHCiMzr9V9skNrj5F9eXc96lNZN3R5MVLsTF97nV922JIzyCrZ668khYPrn1jl5pCBpYDQ3rskgmZ+nnjg7M9vRAfTowEydSEGtsKjXUSaaKui2RDUuX8ZwxVcBTRng978Gh9s4mdRxs+mlv3gP1xQHdpa0mYMG0yGzLcWOTgrkt27sAwFnuXj9WtlEAgz/1DYntujKPxilMVGRow==',
    +                'Wechatpay-Signature' => 'NmmOwkXg89J9UP9gnoGeGZUdSflYhOzD/Imxv0SZf09+42Yn+u8DHQs/QcsOtD1O9hi38PizLnyMQ7NyqkQqVZCu7ID532FOiKkU6qIhrrCrm8w5ktJTXUorH8gEQtxZSKJ0Z0I/fsOBhnvoBRRlIyvEwoESAcJuyJYCgQuvFaqGYDOjLW7umTdO0vUZnH9TJfxfziLxwEYoH09D43H+hXL4oKAF+aIdAiWyS/CwnE4BB8j4NGsCi4v4cAZkJjqV45koAtzXVBzYjccURNSRUYOZv9IW7CqOFmOWsmAN5bVncs4S89lMNW+UIqNRx4tpIrU4CuX81V0tVFcweKnqNQ==',
                     'Wechatpay-Timestamp' => '1626444144',
                     'Wechatpay-Serial' => '45F59D4DABF31918AFCEC556D5D2C6E376675D57',
                 ],
    
  • tests/TestCase.php+4 1 modified
    @@ -43,7 +43,10 @@ protected function setUp(): void
                         'mch_public_cert_path' => __DIR__.'/Cert/wechatAppPublicKey.pem',
                         'notify_url' => 'https://pay.yansongda.cn',
                         'wechat_public_cert_path' => [
    -                        '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__.'/Cert/wechatPublicKey.crt',
    +                        // 注意:正常情况下此处应配置微信官方公钥(wechatPublicKey.crt),但由于单元测试中的签名
    +                        // 均使用 wechatAppPrivateKey.pem 生成,而 wechatPublicKey.crt 对应的私钥我们并不持有,
    +                        // 因此测试环境特殊地将 serial 映射到 wechatAppPublicKey.pem,以保证验签可以通过。
    +                        '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__.'/Cert/wechatAppPublicKey.pem',
                             'yansongda' => __DIR__.'/Cert/wechatPublicKey.crt',
                         ],
                         'mode' => Pay::MODE_NORMAL,
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.