A critical vulnerability exists in the Stripe webhook handler that allows an unauthenticated attacker to forge webhook events and credit arbitrary quota to their account without making any payment. The vulnerability stems from three compounding flaws:
StripeWebhookSecret is empty (the default).Recharge function does not validate that the order's PaymentMethod matches the callback source, enabling cross-gateway exploitation — an order created via any payment method (e.g., Epay) can be fulfilled through a forged Stripe webhook.controller/topup_stripe.go — StripeWebhook(), sessionCompleted()model/topup.go — Recharge(), RechargeCreem(), RechargeWaffo()controller/topup.go — EpayNotify()controller/topup_creem.go — CreemAdaptor.RequestPay() (missing PaymentMethod field)router/api-router.go — webhook route registered without any guardThe StripeWebhookSecret setting defaults to an empty string "". The Stripe Go SDK (webhook.ConstructEventWithOptions) does not reject empty secrets — it computes HMAC-SHA256 with an empty key, producing a deterministic and publicly computable signature.
Vulnerable code (controller/topup_stripe.go):
func StripeWebhook(c *gin.Context) {
// No check for empty StripeWebhookSecret
payload, _ := io.ReadAll(c.Request.Body)
signature := c.GetHeader("Stripe-Signature")
endpointSecret :=...
0.12.10Exploitability
AV:NAC:LPR:LUI:NScope
S:UImpact
C:NI:HA:L7.1/CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L