Skip to main content

New API CVE-2026-41432

HIGH
Insufficient Verification of Data Authenticity (CWE-345)
2026-04-24 https://github.com/QuantumNous/new-api GHSA-xff3-5c9p-2mr4
8.2
CVSS 3.1 · NVD
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Register user account
  2. Delivery
    Create pending top-up order via any gateway
  3. Exploit
    Retrieve order trade_no
  4. Execution
    Forge Stripe webhook signed with empty-key HMAC
  5. Impact
    Credit unlimited quota without payment

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A08:2025 - Software or Data Integrity Failures
ASVS 5.0
V15 - Secure Coding and Architecture Data authenticity verification
Exploitation Conditions

Exploitation requires that StripeWebhookSecret is left at its empty-string default (the single most important precondition - any non-empty value defeats the empty-key HMAC forgery of Flaw 1) and that at least one payment gateway (Epay, Creem, Waffo, or Stripe) is configured so the attacker can create a pending order whose trade_no can be fulfilled cross-gateway. The attacker must also hold a registered account and read the pending order's trade_no via GET /api/user/topup/self. Limiting factors: an operator who has set a non-empty webhook secret, or who blocks /api/stripe/webhook at a reverse proxy when Stripe is unused, is protected against Flaw 1; closed/disabled self-registration removes the account prerequisite. Flaws 2 (missing payment_status=='paid' check) and 3 (missing PaymentMethod validation) are only fully closed by upgrading to v0.12.10 - per the vendor, upgrading is the only complete fix.

Impact

Signals diverge sharply. The flaw is trivially exploitable against default configurations: the Stripe webhook route is unauthenticated with no rate limiting, the default empty StripeWebhookSecret lets the Stripe Go SDK validate an HMAC computed with an empty key (publicly reproducible), and Recharge() fulfills orders from any gateway by trade_no without checking PaymentMethod - so the input CVSS of 8.2 (AV:N/AC:L/PR:N/UI:N, I:H) is credible on mechanism. However, EPSS is only 0.02% (6th percentile), the CVE is NOT in CISA KEV, and the PoC is a reference (advisory pseudocode) not verified as working exploit code - indicating no evidence of widespread active exploitation despite high theoretical severity. The vuln.today decision label is 'this_week' (not act_now/emergency). One nuance against the input's PR:N: practical exploitation requires the attacker to hold a registered account and own a pending top-up order to supply its trade_no, so authentication-level qualifiers should be read with that caveat (reflected in my independent PR:L assessment). Net: a genuine, easy-to-exploit integrity/financial-fraud bug that operators of this specific product should patch promptly, but the low EPSS and limited deployment footprint argue it is a per-deployment priority rather than an internet-wide mass-exploitation event.

Exploit ScenarioDerived

An attacker registers an account, creates a pending top-up order through any configured gateway (e.g. Epay), reads its trade_no, and POSTs a forged Stripe checkout.session.completed payload to /api/stripe/webhook signed with an empty-key HMAC-SHA256 that passes verification because the default webhook secret is blank. The server credits the full quota without payment and the forgery can be repeated for unlimited credits; a public PoC reference exists but it is not verified as working exploit code.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.0% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv3 – Oct 26, 2026

New API (QuantumNous new-api) before 0.12.10 credits AI quota from forged Stripe webhook events: StripeWebhookSecret defaults to an empty string, so the HMAC-SHA256 signature over a crafted checkout.session.completed payload is publicly computable, and the handler never checks payment_status or that the completed order was actually created through Stripe. A registered account holder can therefore open a pending top-up order via any other configured gateway (Epay, Creem, Waffo), read its trade_no from GET /api/user/topup/self, and replay it through a self-signed Stripe webhook to mark the order successful and add quota without paying - with the fraudulent top-up logging as a normal success. There is no CISA KEV listing; a public PoC reference exists but it is not verified as working exploit code, and EPSS is 0.02% (6th percentile), so the vendor's 'this week' priority reflects the insecure default rather than observed exploitation.

Earlier versions of this analysis (2)
v2 Oct 26, 2026 - 18:48 cvss changed CVSS 8.2

Unauthenticated attackers can forge Stripe webhook events against QuantumNous New API deployments to credit themselves unlimited quota without paying. The shipped default leaves StripeWebhookSecret empty, so the Stripe Go SDK validates an attacker-computed HMAC-SHA256 signature made with an empty key, and because the recharge routine looks orders up solely by trade_no without checking the order's payment method, an order created through any configured gateway (Epay, Creem, Waffo) can be completed via the forged Stripe callback. A public PoC reference exists but is not verified as working exploit code; there is no KEV entry and EPSS is very low (0.02%, 6th percentile), yet the vendor-rated CVSS 3.1 score is 8.2 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L) because exploitation requires no privileges or user interaction when the default configuration is in place.

v1 Apr 24, 2026 - 16:16 CVSS 7.1

Attackers can forge Stripe webhook events to obtain unlimited API quota without payment in QuantumNous new-api (Go package github.com/QuantumNous/new-api). The vulnerability exploits an empty default webhook secret that allows HMAC signature forgery, missing payment status validation, and cross-gateway order fulfillment logic that permits completing orders created through any payment provider (Epay, Creem, Waffo) via fabricated Stripe callbacks. Virtually all deployments with any payment method enabled are vulnerable in default configuration. Fixed in version 0.12.10. No public exploit code identified at time of analysis, but the detailed advisory includes a proof-of-concept pseudocode demonstrating the attack chain. CVSS 7.1 (High) with low attack complexity and low privileges required indicates practical exploitation risk for deployed instances.

RemediationAI

Vendor-released patch: upgrade to v0.12.10, which per the advisory is the only complete fix because it adds the empty-secret rejection, the payment_status == "paid" check plus async_payment_succeeded/async_payment_failed handling, PaymentMethod validation in Recharge/RechargeCreem/RechargeWaffo/EpayNotify, and the missing PaymentMethod field on Creem order creation (release notes: https://github.com/QuantumNous/new-api/releases/tag/v0.12.10). If upgrading is not immediately possible, apply both listed workarounds: first set StripeWebhookSecret in the admin panel (Payment -> Stripe) to any non-empty random string - the vendor notes it need not be a real Stripe secret to defeat the empty-key HMAC forgery, but if Stripe is used in production you must substitute the real signing secret from the Stripe Dashboard, otherwise legitimate webhooks will fail verification and paid orders will not be fulfilled; second, if Stripe is not in use, deny the endpoint at the reverse proxy (e.g. Nginx location = /api/stripe/webhook { return 403; }), accepting that this permanently disables Stripe checkout until removed. The advisory is explicit that these workarounds only close Flaw 1 (empty-secret bypass) and leave Flaw 2 (missing payment_status verification) and Flaw 3 (cross-gateway order fulfilment) open until v0.12.10 is installed.

Affected Packages

go github.com/quantumnous/new-api fix: 0.12.10

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in go

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

New API is a Go/Gin web service that proxies multiple AI providers and sells quota through pluggable payment adaptors (Stripe, Epay, Creem, Waffo). The Stripe path uses the official Go SDK's webhook.ConstructEventWithOptions, which computes an HMAC-SHA256 over the timestamp plus raw body using the configured endpoint secret; an empty secret is not rejected, so the signature becomes a deterministic value anyone can compute (CWE-345 Insufficient Verification of Data Authenticity, rooted in the CWE-1188 insecure default of an empty StripeWebhookSecret). The route POST /api/stripe/webhook is registered without authentication middleware or rate limiting, and sessionCompleted only checks status == "complete", ignoring payment_status semantics for delayed methods and never handling checkout.session.async_payment_succeeded or async_payment_failed. The fulfilment sink is model.Recharge(), which selects any pending order by trade_no alone and increments the user's quota without validating PaymentMethod, allowing cross-gateway order fulfilment (CWE-863 Incorrect Authorization); the Creem adaptor additionally never sets PaymentMethod on order creation. The Go module is tracked as pkg:go/github.com_quantumnous_new-api.

Know when Stripe gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

NVD PRIMARY 8.2 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:L
vuln.today AI 6.5 MEDIUM

Network-reachable unauthenticated webhook, but practical exploitation needs a self-registered account owning a pending order, so PR:L; default empty secret keeps AC:L; impact is integrity-only (I:H), no confidentiality, availability indirect.

3.1 AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N
4.0 AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
SUSE HIGH

Primary rating from NVD.

CVSS VectorNVD

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
High
Availability
Low

Lifecycle Timeline

5
Analysis Updated
Oct 26, 2026 - 18:49 vuln.today
v3 - CVSS changed
Analysis Updated
Oct 26, 2026 - 18:48 vuln.today
v2 - CVSS changed
CVSS changed
Oct 26, 2026 - 18:23 NVD
7.1 (HIGH) 8.2 (HIGH)
Patch released
Apr 25, 2026 - 02:30 nvd
Patch available
CVE Published
Apr 24, 2026 - 15:43 nvd
HIGH 7.1

DescriptionNVD

Summary

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:

  1. The Stripe webhook endpoint does not reject requests when StripeWebhookSecret is empty (the default).
  2. When the HMAC secret is empty, any attacker can compute valid webhook signatures, effectively bypassing signature verification entirely.
  3. The 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.

Affected Components

  • 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 guard

CWE Classification

  • CWE-345: Insufficient Verification of Data Authenticity
  • CWE-1188: Initialization with an Insecure Default (empty webhook secret)
  • CWE-863: Incorrect Authorization (cross-gateway order fulfillment)

Vulnerability Details

Flaw 1: Empty Webhook Secret Bypasses Signature Verification

The 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):

go
func StripeWebhook(c *gin.Context) {
    // No check for empty StripeWebhookSecret
    payload, _ := io.ReadAll(c.Request.Body)
    signature := c.GetHeader("Stripe-Signature")
    endpointSecret := setting.StripeWebhookSecret // defaults to ""
    event, err := webhook.ConstructEventWithOptions(payload, signature, endpointSecret, ...)
    // When secret is "", attacker can compute valid HMAC with the same empty key
}

The webhook route is unconditionally registered with no authentication middleware and no rate limiting:

go
apiRouter.POST("/stripe/webhook", controller.StripeWebhook)

Flaw 2: Missing payment_status Verification

The sessionCompleted handler only checks status "complete" but does not verify payment_status "paid". Stripe's checkout.session.completed event can fire with payment_status = "unpaid" for delayed payment methods (bank transfer, SEPA, Boleto, etc.) or payment_status = "no_payment_required" for 100% discount coupons.

Additionally, checkout.session.async_payment_succeeded and checkout.session.async_payment_failed events are not handled, so delayed payments that ultimately fail are never rolled back.

Flaw 3: Cross-Gateway Order Fulfillment (No PaymentMethod Validation)

The model.Recharge() function (called by the Stripe webhook) looks up orders solely by trade_no and does not validate that the order's PaymentMethod is "stripe":

go
func Recharge(referenceId string, customerId string) (err error) {
    // Finds ANY pending order by trade_no, regardless of PaymentMethod
    tx.Where("trade_no = ?", referenceId).First(topUp)
    if topUp.Status != "pending" { return }
    // Credits quota without checking topUp.PaymentMethod
    quota = topUp.Money * QuotaPerUnit
    tx.Model(&User{}).Update("quota", gorm.Expr("quota + ?", quota))
}

This allows an attacker to create orders through any configured payment gateway (Epay, Creem, Waffo) and then complete them via a forged Stripe webhook - even if Stripe itself was never configured.

Attack Scenario

Prerequisites: Any payment method is configured (e.g., Epay) + StripeWebhookSecret is empty (default).

  1. Attacker registers a user account.
  2. Attacker calls POST /api/user/pay to create an Epay top-up order (e.g., amount=10000). The order is stored with status=pending.
  3. Attacker queries GET /api/user/topup/self to retrieve the trade_no of the pending order.
  4. Attacker computes HMAC-SHA256 with an empty key over a crafted checkout.session.completed payload containing the stolen trade_no as client_reference_id.
  5. Attacker sends POST /api/stripe/webhook with the forged payload and signature header.
  6. The server verifies the signature (passes because the secret is empty), calls Recharge(), which finds the Epay order by trade_no, marks it as success, and credits the full quota.
  7. Attacker repeats steps 2-6 indefinitely for unlimited credits.

Proof of concept (pseudocode):

python
import hmac, hashlib, time, json, requests

timestamp = int(time.time())
payload = json.dumps({
    "type": "checkout.session.completed",
    "data": {
        "object": {
            "client_reference_id": "<trade_no from step 3>",
            "status": "complete",
            "payment_status": "paid",
            "customer": "cus_fake",
            "amount_total": "0",
            "currency": "usd"
        }
    }
})
# Empty secret = publicly computable signature
sig = hmac.new(b"", f"{timestamp}.{payload}".encode(), hashlib.sha256).hexdigest()
header = f"t={timestamp},v1={sig}"

requests.post("https://target/api/stripe/webhook",
    data=payload,
    headers={"Stripe-Signature": header, "Content-Type": "application/json"})

Remediation

Fix 1: Reject webhooks when secret is empty

go
func StripeWebhook(c *gin.Context) {
    if setting.StripeWebhookSecret == "" {
        c.AbortWithStatus(http.StatusForbidden)
        return
    }
    // ... existing logic
}

Fix 2: Verify payment_status and handle async payment events

go
func sessionCompleted(event stripe.Event) {
    // ... existing status check ...
    paymentStatus := event.GetObjectValue("payment_status")
    if paymentStatus != "paid" {
        return // Wait for async_payment_succeeded event
    }
    fulfillOrder(event, referenceId, customerId)
}

Add handlers for checkout.session.async_payment_succeeded and checkout.session.async_payment_failed.

Fix 3: Validate PaymentMethod in all recharge functions

go
// In model.Recharge (Stripe):
if topUp.PaymentMethod != "stripe" {
    return ErrPaymentMethodMismatch
}

// In model.RechargeCreem:
if topUp.PaymentMethod != "creem" {
    return ErrPaymentMethodMismatch
}

// In model.RechargeWaffo:
if topUp.PaymentMethod != "waffo" {
    return ErrPaymentMethodMismatch
}

// In controller.EpayNotify:
if topUp.PaymentMethod == "stripe" || topUp.PaymentMethod == "creem" || topUp.PaymentMethod == "waffo" {
    return // reject cross-gateway fulfillment
}

Additional fix: Set PaymentMethod on Creem order creation

The Creem order creation was missing the PaymentMethod field entirely:

go
topUp := &model.TopUp{
    // ...
    PaymentMethod: "creem", // was missing
}

Patched Versions

  • v0.12.10 - includes all three fixes described above.

All users are strongly encouraged to upgrade immediately.

Workaround (for users unable to upgrade immediately)

If users cannot upgrade to v0.12.10 right away, apply all of the following mitigations:

  1. Set StripeWebhookSecret to any non-empty value. Go to the admin panel → Payment → Stripe, and set the Webhook Signing Secret to any random string (e.g., whsec_placeholder_do_not_leave_empty). It does not need to be a real Stripe secret - any non-empty value will prevent the empty-key HMAC forgery. This is the single most important step - it closes the primary attack vector. If Stripe payments are used in production, replace with the real secret from the project's Stripe Dashboard → Webhooks to ensure legitimate webhooks continue to work.
  2. If Stripe is not in use, block the webhook endpoint. If users have not configured Stripe payments, use a reverse proxy (Nginx, Caddy, etc.) to deny access to /api/stripe/webhook:
nginx
   location = /api/stripe/webhook {
       return 403;
   }

> Note: The workaround only mitigates Flaw 1 (empty secret bypass). Flaws 2 (missing payment_status check) and 3 (cross-gateway fulfillment) are only fully addressed in v0.12.10. Upgrading is the only complete fix.

Impact

  • Financial fraud: Attacker obtains unlimited API quota without payment.
  • Operator financial loss: Fraudulent quota is consumed against upstream AI providers (OpenAI, Anthropic, Google, etc.), charged to the operator.
  • Silent exploitation: Fraudulent top-ups appear as normal successful transactions in system logs, making detection difficult.
  • Wide exposure: The default insecure configuration means virtually all deployments with any payment method enabled are vulnerable.

Timeline

  • 2025-04-15: Vulnerability reported by @ChangeYu0229
  • 2025-04-15: Vulnerability confirmed and root cause analysis completed
  • 2025-04-15: Fix developed and applied
  • 2025-04-15: Patched in v0.12.10

Resources

Executive ViewAI

Why It Matters

New API (QuantumNous) versions before 0.12.10 contain a critical flaw that allows any registered user to fraudulently obtain AI compute quota without payment. This directly impacts revenue integrity and resource consumption, enabling unauthorized usage that could lead to financial losses and service degradation for legitimate customers.

Business Impact: High
Compensating Controls

Vendor-released patch: 0.12.10

Threat Intelligence Overview

EPSS Score
0.0%
Top 94% exploitable
Prevalence
Low
niche self-hosted LLM API gateway, modest open-source deployment footprint
Threat Intel
1
1 sources
Exploit
POC
Public exploit code exists
Data Quality
6 sources
Confidence: High
NVD CVE.org EPSS GHSA POC (1) Vendor GitHub VulDB

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC Yes
EPSS 0.0%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Out-of-Cycle
Exploitation· derived
Poc
System Exposure· derived
Open
Automatable· derived
Yes
Human Impact
High

Priority Score

61
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +41
PoC: +20
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Affected Products (CPE)NVD

pkg:go/github.com_quantumnous_new-api

Vendor StatusVendor

SUSE

Severity: Important
Product Status
SUSE Linux Enterprise Server 16.1 Affected
SUSE Linux Enterprise Server for SAP applications 16.1 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP5 Affected
SUSE Linux Enterprise Module for Package Hub 15 SP6 Affected
openSUSE Leap 15.5 Affected

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