DocsQuick StartAI News
AI NewsNew-API Critical Vulnerability: Allows Forging of Arbitrary Top-Ups
Industry News

New-API Critical Vulnerability: Allows Forging of Arbitrary Top-Ups

2026-04-20
New-API Critical Vulnerability: Allows Forging of Arbitrary Top-Ups

A vulnerability has been reported in the open-source AI relay project **New-API**, where the Stripe Webhook signature verification can be bypassed, allowing attackers to forge recharges of arbitrary amounts. The official team has released version **v0.12.10** to fix the issue. All site administrators should upgrade immediately and review historical orders.

New-API Critical Vulnerability: Stripe Signature Verification Practically Useless, Attackers Can Forge Top-Ups of Any Amount

If you are using New-API to build an AI relay station and have enabled Stripe payments—put everything on hold and upgrade first.

On April 17, the security community disclosed a critical vulnerability in the open-source project New-API: under certain configurations, attackers can completely bypass Stripe Webhook signature verification and forge arbitrary recharge events into the system. In other words, they can top-up any balance amount without spending a cent.

The project maintainers have fixed this issue in v0.12.10. However, considering how widely New-API is used among domestic AI relay station operators, this incident deserves serious attention from every site owner.


Where exactly is the vulnerability?

To understand it, let’s briefly review how Stripe Webhooks work.

When a user completes a payment on your relay station, Stripe doesn’t directly tell your frontend “the money’s in.” It uses asynchronous notifications. Stripe’s server sends a POST request to your preconfigured Webhook URL, containing payment event data in JSON form (like checkout.session.completed). When your backend receives it, it must perform one crucial task: signature verification.

The logic is simple: when sending the request, Stripe uses your Dashboard-generated Webhook Signing Secret (usually beginning with whsec_) to create an HMAC signature of the request body, storing it in the Stripe-Signature header. Your server calculates the signature again using the same secret, compares both, and confirms whether the request really comes from Stripe instead of a forged attacker’s request.

The problem lies in how New-API handles the edge case of an “empty secret.”

In older versions, the logic looked roughly like this:

// Pseudocode reconstructing the vulnerability logic
func handleStripeWebhook(c *gin.Context) {
    payload, _ := io.ReadAll(c.Request.Body)
    sigHeader := c.GetHeader("Stripe-Signature")
    
    // Read the Webhook Secret from config
    endpointSecret := config.StripeWebhookSecret
    
    // Critical issue: Even when endpointSecret is empty, signature verification is still attempted
    event, err := webhook.ConstructEvent(payload, sigHeader, endpointSecret)
    if err != nil {
        // Signature verification failure behavior depends on how the Stripe SDK handles an empty secret
        // ...
    }
    
    // Continue processing payment event and credit balance...
}

Normally, if the station owner enables Stripe payments but does not configure the Webhook Signing Secret (or sets it as an empty string), the code should reject all incoming Webhook requests—without a key you can’t verify any signature, allowing them through means total exposure.

But the old version of New-API didn’t perform that preliminary check. It still passed the empty secret to the Stripe SDK’s signature verification function. Under certain conditions, this verification procedure could be bypassed, meaning the security boundary of signature verification completely collapses.

Diagram of the New-API Stripe Webhook vulnerability, showing how attackers forge payment events and bypass signature verification

An attacker only needs to:

  1. Find the target station’s Webhook endpoint (usually a fixed path like /api/stripe/webhook)
  2. Construct a forged Stripe payment success JSON event
  3. Send it directly via POST

The system obediently records the “recharge” into the corresponding account balance.

This isn’t a complex attack chain nor requires deep security expertise. Anyone familiar with Stripe Webhook’s data format could pull it off with a simple curl command.


How widespread is the impact?

To summarize: not all New-API users are affected, but the affected ones are in serious danger.

Two conditions must be met:

  1. Stripe is enabled as a payment method
  2. StripeWebhookSecret is not configured correctly (empty or unset)

If your relay station only uses other payment methods (like Epay or TigerPay), or you use Stripe but followed the docs properly to set up the Webhook Secret, this vulnerability won’t directly affect you.

But in reality, New-API is one of the most popular open-source projects in China’s AI relay station ecosystem. Many station owners just “follow tutorials” to set things up, without fully understanding Stripe’s configuration details. Especially smaller operators might skip Webhook Secret setup during testing and then forget to finalize it after launch.

What’s worse, exploiting this kind of vulnerability leaves almost no clear trace. Forged top-ups appear as normal Stripe callbacks inside the system. Unless you carefully cross-check transaction logs against Stripe Dashboard’s actual payments one by one, anomalies are hard to notice.


Fix: What v0.12.10 did

In the latest version New-API v0.12.10, the developer took a very direct approach—added a hard check at the entry point:

// Fixed logic (pseudocode)
func handleStripeWebhook(c *gin.Context) {
    endpointSecret := config.StripeWebhookSecret
    
    // New: Explicitly check if secret is empty
    if endpointSecret == "" {
        c.JSON(403, gin.H{"error": "Stripe webhook secret not configured"})
        return  // Immediately terminate, do not proceed further
    }
    
    payload, _ := io.ReadAll(c.Request.Body)
    sigHeader := c.GetHeader("Stripe-Signature")
    
    event, err := webhook.ConstructEvent(payload, sigHeader, endpointSecret)
    if err != nil {
        c.JSON(400, gin.H{"error": "Invalid signature"})
        return
    }
    
    // Signature verified, continue processing...
}

The logic is simple: if Stripe is enabled but no secret is configured, the system returns 403 Forbidden and stops processing right away—giving no chance for bypassing.

This is a textbook example of defensive programming—don’t rely on downstream functions to handle exceptional input, block illegal states at the top level.


What station owners should do now

If you run a relay station using New-API, here’s a priority-ordered checklist:

1. Immediately upgrade to v0.12.10 or higher

The most urgent step. Regardless of whether you use Stripe, upgrading is safe—just do it.

# For Docker deployment
docker pull calciumion/new-api:latest
docker compose down && docker compose up -d

# For source deployment
git pull origin main
go build -o new-api
# Restart service

2. Check your Stripe Webhook Secret configuration

Log in to your Stripe Dashboard → Developers → Webhooks, confirm the endpoint configuration and ensure the Signing Secret is copied into your New-API settings.

If you haven’t configured it before, do it now. If you don’t use Stripe at all, consider disabling Stripe payments in the New-API backend.

3. Audit historical recharge records

This step takes the most time but may be the most crucial.

  • Export all recent Stripe-based recharge records from the New-API database
  • Compare each with Stripe Dashboard’s actual payment records
  • Focus on those with unusual large amounts, dense recharge timestamps, or sudden changes in user spending patterns

If you find recharge records without corresponding actual payments in Stripe, they are likely forged.

4. Check network exposure of your Webhook endpoint

Ideally, your Webhook endpoint should only accept requests from Stripe’s IP ranges. Although signature verification is the final defense line, network-layer filtering (like an IP whitelist in Nginx) provides extra protection.

Stripe officially publishes the IP ranges used for Webhook requests—refer to their documentation to configure this.


Broader lessons from this incident

The vulnerability itself isn’t technically sophisticated, and the fix is simple. But it highlights a growing issue in the open-source AI infrastructure space: security priorities are often severely underestimated amidst rapid feature iteration.

Projects like New-API’s relay station essentially operate as SaaS systems involving financial transactions—user top-ups, spending, balance management—all financial-grade operations. Yet most open-source projects’ security audits fall short of matching that level of responsibility.

This isn’t blaming New-API’s developers. As an open-source project, its completeness is already impressive. The issue is that once such a project becomes widely used in production, the community needs more systematic security review mechanisms—rather than waiting until vulnerabilities are found or exploited.

Similar signature bypass issues have occurred in other Webhook integrations—not just Stripe, but WeChat Pay and Alipay callbacks too. The key takeaway is simple: Never trust external input, always explicitly validate preconditions.

For developers using various AI relay services, this also serves as a reminder: when choosing a relay station, besides pricing and model coverage, the platform's security capability and operational maturity are equally important. Commercial aggregation platforms like OpenAI Hub offer more robust payment security and API key management—this is a critical difference between self-hosted and managed solutions.


General Webhook security principles

Let’s summarize a few best practices for Webhook security beyond Stripe, applicable to all asynchronous payment integrations:

  1. Signing key must not be empty: Explicitly check in code; reject requests if the key is missing.
  2. Use the latest signature scheme: Stripe’s v1 uses HMAC-SHA256; make sure you’re not using deprecated methods.
  3. Verify timestamp tolerance: Stripe signatures include a timestamp; set a reasonable tolerance window (usually 5 minutes) to prevent replay attacks.
  4. Idempotent handling: The same event ID should not be processed twice; use database uniqueness constraints or Redis deduplication.
  5. Network-level filtering: Restrict your Webhook endpoint at Nginx/CDN layer to accept requests only from payment provider IPs.
  6. Logging and alerts: Record detailed logs for all Webhook requests; set up alerts for failed verifications.
  7. Periodic key rotation: Stripe allows multiple active secrets, enabling seamless secret rotation.

These may sound like common sense, but in practice—especially in fast-moving open-source projects—common sense is often what gets skipped first.


In conclusion

New-API’s response to this vulnerability was fairly quick. Version v0.12.10 was released soon after disclosure, and the changelog clearly addressed the issue and fix—showing admirable transparency within the open-source community.

But “fast fix” doesn’t mean “no damage.” How long did the vulnerability exist before disclosure? How many sites were unknowingly exposed? Those questions might never be answered.

So if you’re a New-API user: upgrade now, audit now.

Don’t wait until the next headline reads “AI relay station loses tens of thousands due to vulnerability” and realize you’re the protagonist.


References

Related Articles

View All

Contact Us

We usually reply quickly during business hours

Scan WeChat

Support: Hub Assistant

WeChat ID: