PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.5.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.5.0
4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Middleware / WebhooksMiddleware.php
surecart / app / src / Middleware Last commit date
AccountClaimMiddleware.php 3 years ago AdminColorMiddleware.php 2 years ago ArchiveModelMiddleware.php 2 months ago BrandColorMiddleware.php 3 years ago CheckoutFormModeMiddleware.php 2 months ago CheckoutRedirectMiddleware.php 3 years ago ComponentAssetsMiddleware.php 3 years ago CustomerDashboardLinkRedirectMiddleware.php 1 year ago CustomerDashboardRedirectMiddleware.php 1 year ago EditModelMiddleware.php 2 months ago InvoiceRedirectMiddleware.php 1 year ago LoginLinkMiddleware.php 1 year ago LoginMiddleware.php 2 years ago NonceMiddleware.php 3 years ago OrderRedirectMiddleware.php 3 years ago PathRedirectMiddleware.php 3 years ago PaymentFailureRedirectMiddleware.php 3 years ago ProductReviewRedirectMiddleware.php 4 months ago PurchaseRedirectMiddleware.php 3 years ago SubscriptionRedirectMiddleware.php 3 years ago UpsellMiddleware.php 2 years ago WebhooksMiddleware.php 2 months ago
WebhooksMiddleware.php
112 lines
1 <?php
2
3 namespace SureCart\Middleware;
4
5 use Closure;
6 use SureCart\Models\RegisteredWebhook;
7 use SureCartCore\Requests\RequestInterface;
8
9 /**
10 * Middleware for handling model archiving.
11 */
12 class WebhooksMiddleware {
13 /**
14 * Holds the current request.
15 *
16 * @var RequestInterface
17 */
18 protected $request;
19
20 /**
21 * Handle the middleware.
22 *
23 * @param RequestInterface $request Request.
24 * @param Closure $next Next.
25 * @return function
26 */
27 public function handle( RequestInterface $request, Closure $next ) {
28 $this->request = $request;
29
30 if ( ! $this->verifySignature( $request ) ) {
31 return \SureCart::json( [ 'error' => 'Invalid signature' ] )->withStatus( 403 );
32 }
33
34 return $next( $request );
35 }
36
37 /**
38 * Verify the signature.
39 *
40 * Fails closed when no signing secret is registered — see CVE-2026-7655.
41 * Uses hash_equals() for a timing-safe comparison.
42 *
43 * @return bool
44 */
45 public function verifySignature() {
46 $secret = $this->getSigningSecret();
47 if ( ! is_string( $secret ) || '' === $secret ) {
48 return false;
49 }
50 return hash_equals( (string) $this->computeHash( $secret ), (string) $this->getSignature() );
51 }
52
53 /**
54 * Compute an HMAC with the SHA256 hash function.
55 * Use the endpoint’s signing secret as the key, and use the signed_payload string as the message.
56 *
57 * @param string|null $secret Optional signing secret. Falls back to getSigningSecret() when null.
58 * @return string
59 */
60 public function computeHash( $secret = null ) {
61 if ( null === $secret ) {
62 $secret = $this->getSigningSecret();
63 }
64 return hash_hmac( 'sha256', $this->getSignedPayload(), (string) $secret );
65 }
66
67 /**
68 * Get the signing secret.
69 *
70 * @return string
71 */
72 public function getSigningSecret() {
73 return RegisteredWebhook::getSigningSecret();
74 }
75
76 /**
77 * Get expected json request body.
78 *
79 * @return string
80 */
81 public function getBody() {
82 return file_get_contents( 'php://input' );
83 }
84
85 /**
86 * Get the webhook signature.
87 *
88 * @return string
89 */
90 public function getSignature() {
91 return $this->request->headers( 'X-Webhook-Signature' )[0] ?? $this->request->headers( 'x-webhook-signature' )[0] ?? '';
92 }
93
94 /**
95 * Get the webhook timestamp.
96 *
97 * @return string
98 */
99 public function getTimestamp() {
100 return $this->request->headers( 'X-Webhook-Timestamp' )[0] ?? $this->request->headers( 'x-webhook-timestamp' )[0] ?? '';
101 }
102
103 /**
104 * Get the signed payload.
105 *
106 * @return string
107 */
108 public function getSignedPayload() {
109 return $this->getTimestamp() . '.' . $this->getBody();
110 }
111 }
112