Common Weakness Enumeration

CWE-863

Allowed-with-Review

Incorrect Authorization

Abstraction: Class · Status: Incomplete

The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check.

6038 vulnerabilities reference this CWE, most recent first.

GHSA-XCW2-CX77-J362

Vulnerability from github – Published: 2025-09-04 21:31 – Updated: 2025-09-05 18:31
VLAI
Details

In onCreate of SelectAccountActivity.java, there is a possible way to add contacts without permission due to a logic error in the code. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2025-48523"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2025-09-04T19:15:38Z",
    "severity": "HIGH"
  },
  "details": "In onCreate of SelectAccountActivity.java, there is a possible way to add contacts without permission due to a logic error in the code. This could lead to local escalation of privilege with no additional execution privileges needed. User interaction is not needed for exploitation.",
  "id": "GHSA-xcw2-cx77-j362",
  "modified": "2025-09-05T18:31:19Z",
  "published": "2025-09-04T21:31:38Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-48523"
    },
    {
      "type": "WEB",
      "url": "https://android.googlesource.com/platform/packages/apps/Contacts/+/7c8dbcffbc9382fcdb788919106c3b0525db83ab"
    },
    {
      "type": "WEB",
      "url": "https://source.android.com/security/bulletin/2025-09-01"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XCX6-4F2G-HHGX

Vulnerability from github – Published: 2026-07-24 21:17 – Updated: 2026-07-24 21:17
VLAI
Summary
Budibase: S3 presigned URL endpoint authorization regression in v3.39.4 allows BASIC users to obtain S3 PutObject presigned URLs
Details

Impact

In Budibase v3.39.4, a regression in the authorization level for the S3 attachment upload endpoint allows any BASIC app user to obtain S3 PutObject presigned URLs. The endpoint uses TABLE/WRITE permission level instead of the intended BUILDER level defined in v3.39.3. Additionally, the controller does not pin the target bucket to the datasource's configured bucket, allowing writes to any S3 bucket the stored IAM credentials can access.

Reproduction

  1. As a BASIC app user, discover or obtain a valid S3 datasource ID within the app
  2. Send a POST request:
POST /api/attachments/<datasourceId>/url
Content-Type: application/json
x-budibase-app-id: <appId>

{"bucket": "target-bucket", "key": "malicious-file.html"}
  1. The response contains a valid S3 PutObject presigned URL
  2. Use the presigned URL to upload arbitrary content to any writable S3 bucket in the IAM credential scope

Root Cause

The /api/attachments/:datasourceId/url route was changed from authorized(BUILDER) in v3.39.3 to authorized(PermissionType.TABLE, PermissionLevel.WRITE) in v3.39.4. BASIC users have TABLE/WRITE permissions by default, so they can call this endpoint. The controller at packages/server/src/api/controllers/static/index.ts:614-632 accepts the bucket parameter directly from the request body and passes it to getSignedUrl without validating against the datasource's configured bucket.

Evidence

The test suite at packages/server/src/api/routes/tests/static.spec.ts:218-235 confirms this behavior. The test authenticates as a BASIC role user and successfully generates a signed upload URL, verifying HTTP 200 and a defined res.body.signedUrl.

Remediation

  1. Restore the authorized(BUILDER) middleware on the route
  2. Add paramResource("datasourceId") to ensure the datasource belongs to the caller's app
  3. Pin the S3 bucket to datasource.config.bucket in the controller, ignoring the caller-supplied bucket value
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "@budibase/server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "last_affected": "3.38.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-07-24T21:17:03Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "## Impact\n\nIn Budibase v3.39.4, a regression in the authorization level for the S3 attachment upload endpoint allows any BASIC app user to obtain S3 PutObject presigned URLs. The endpoint uses TABLE/WRITE permission level instead of the intended BUILDER level defined in v3.39.3. Additionally, the controller does not pin the target bucket to the datasource\u0027s configured bucket, allowing writes to any S3 bucket the stored IAM credentials can access.\n\n## Reproduction\n\n1. As a BASIC app user, discover or obtain a valid S3 datasource ID within the app\n2. Send a POST request:\n\n```\nPOST /api/attachments/\u003cdatasourceId\u003e/url\nContent-Type: application/json\nx-budibase-app-id: \u003cappId\u003e\n\n{\"bucket\": \"target-bucket\", \"key\": \"malicious-file.html\"}\n```\n\n3. The response contains a valid S3 PutObject presigned URL\n4. Use the presigned URL to upload arbitrary content to any writable S3 bucket in the IAM credential scope\n\n## Root Cause\n\nThe `/api/attachments/:datasourceId/url` route was changed from `authorized(BUILDER)` in v3.39.3 to `authorized(PermissionType.TABLE, PermissionLevel.WRITE)` in v3.39.4. BASIC users have TABLE/WRITE permissions by default, so they can call this endpoint. The controller at `packages/server/src/api/controllers/static/index.ts:614-632` accepts the `bucket` parameter directly from the request body and passes it to `getSignedUrl` without validating against the datasource\u0027s configured bucket.\n\n## Evidence\n\nThe test suite at `packages/server/src/api/routes/tests/static.spec.ts:218-235` confirms this behavior. The test authenticates as a BASIC role user and successfully generates a signed upload URL, verifying HTTP 200 and a defined `res.body.signedUrl`.\n\n## Remediation\n\n1. Restore the `authorized(BUILDER)` middleware on the route\n2. Add `paramResource(\"datasourceId\")` to ensure the datasource belongs to the caller\u0027s app\n3. Pin the S3 bucket to `datasource.config.bucket` in the controller, ignoring the caller-supplied bucket value",
  "id": "GHSA-xcx6-4f2g-hhgx",
  "modified": "2026-07-24T21:17:03Z",
  "published": "2026-07-24T21:17:03Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/Budibase/budibase/security/advisories/GHSA-xcx6-4f2g-hhgx"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/Budibase/budibase"
    },
    {
      "type": "WEB",
      "url": "https://github.com/Budibase/budibase/releases/tag/3.40.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": " Budibase: S3 presigned URL endpoint authorization regression in v3.39.4 allows BASIC users to obtain S3 PutObject presigned URLs"
}

GHSA-XF3P-Q42R-RWGF

Vulnerability from github – Published: 2023-12-05 03:30 – Updated: 2023-12-05 03:30
VLAI
Details

Improper Authentication vulnerability in Samsung Pass prior to version 4.3.00.17 allows physical attackers to bypass authentication due to invalid flag setting.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-42575"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2023-12-05T03:15:18Z",
    "severity": "MODERATE"
  },
  "details": "Improper Authentication vulnerability in Samsung Pass prior to version 4.3.00.17 allows physical attackers to bypass authentication due to invalid flag setting.",
  "id": "GHSA-xf3p-q42r-rwgf",
  "modified": "2023-12-05T03:30:23Z",
  "published": "2023-12-05T03:30:23Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-42575"
    },
    {
      "type": "WEB",
      "url": "https://security.samsungmobile.com/serviceWeb.smsb?year=2023\u0026month=12"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:P/AC:L/PR:H/UI:R/S:U/C:H/I:H/A:N",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XF7M-V66Q-76W8

Vulnerability from github – Published: 2025-11-01 03:30 – Updated: 2025-11-15 02:24
VLAI
Summary
Liferay Portal and DXP do not check permissions of images in a blog entry
Details

Blogs in Liferay Portal 7.4.0 through 7.4.3.111, and older unsupported versions, and Liferay DXP 2023.Q4.0 through 2023.Q4.10, 2023.Q3.1 through 2023.Q3.10, 7.4 GA through update 92, and older unsupported versions does not check permission of images in a blog entry, which allows remote attackers to view the images in a blog entry via crafted URL.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Maven",
        "name": "com.liferay:com.liferay.blogs.item.selector.web"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.0.19"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-62275"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-11-03T21:06:57Z",
    "nvd_published_at": "2025-11-01T03:15:31Z",
    "severity": "MODERATE"
  },
  "details": "Blogs in Liferay Portal 7.4.0 through 7.4.3.111, and older unsupported versions, and Liferay DXP 2023.Q4.0 through 2023.Q4.10, 2023.Q3.1 through 2023.Q3.10, 7.4 GA through update 92, and older unsupported versions does not check permission of images in a blog entry, which allows remote attackers to view the images in a blog entry via crafted URL.",
  "id": "GHSA-xf7m-v66q-76w8",
  "modified": "2025-11-15T02:24:51Z",
  "published": "2025-11-01T03:30:24Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-62275"
    },
    {
      "type": "WEB",
      "url": "https://github.com/liferay/liferay-portal/commit/9856c55bcbb3b8ce1276117709b9c0082a19c62c"
    },
    {
      "type": "WEB",
      "url": "https://github.com/liferay/liferay-portal/commit/e0ae29cfdb8d10a6fddc56d04ca3ae88c3fbc7f3"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/liferay/liferay-portal"
    },
    {
      "type": "WEB",
      "url": "https://liferay.atlassian.net/browse/LPE-17948"
    },
    {
      "type": "WEB",
      "url": "https://liferay.dev/portal/security/known-vulnerabilities/-/asset_publisher/jekt/content/CVE-2025-62275"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Liferay Portal and DXP do not check permissions of images in a blog entry"
}

GHSA-XFC5-HP99-89QR

Vulnerability from github – Published: 2022-05-24 17:45 – Updated: 2022-05-24 17:45
VLAI
Details

The team sync HTTP API in Grafana Enterprise 7.4.x before 7.4.5 has an Incorrect Access Control issue. On Grafana instances using an external authentication service, this vulnerability allows any authenticated user to add external groups to existing teams. This can be used to grant a user team permissions that the user isn't supposed to have.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-28146"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-03-22T14:15:00Z",
    "severity": "MODERATE"
  },
  "details": "The team sync HTTP API in Grafana Enterprise 7.4.x before 7.4.5 has an Incorrect Access Control issue. On Grafana instances using an external authentication service, this vulnerability allows any authenticated user to add external groups to existing teams. This can be used to grant a user team permissions that the user isn\u0027t supposed to have.",
  "id": "GHSA-xfc5-hp99-89qr",
  "modified": "2022-05-24T17:45:03Z",
  "published": "2022-05-24T17:45:03Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-28146"
    },
    {
      "type": "WEB",
      "url": "https://community.grafana.com/t/grafana-enterprise-6-7-6-7-3-10-and-7-4-5-security-update/44724"
    },
    {
      "type": "WEB",
      "url": "https://community.grafana.com/t/release-notes-v6-7-x/27119"
    },
    {
      "type": "WEB",
      "url": "https://grafana.com/blog/2021/03/18/grafana-6.7.6-7.3.10-and-7.4.5-released-with-important-security-fixes-for-grafana-enterprise"
    },
    {
      "type": "WEB",
      "url": "https://grafana.com/docs/grafana/latest/release-notes/release-notes-7-3-10"
    },
    {
      "type": "WEB",
      "url": "https://grafana.com/docs/grafana/latest/release-notes/release-notes-7-4-5"
    },
    {
      "type": "WEB",
      "url": "https://grafana.com/products/enterprise"
    },
    {
      "type": "WEB",
      "url": "https://www.openwall.com/lists/oss-security/2021/03/19/5"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-XFCW-6C56-RP9P

Vulnerability from github – Published: 2022-05-24 17:45 – Updated: 2022-08-13 00:00
VLAI
Details

Using PendingIntent with implicit intent in Bixby Voice prior to version 3.0.52.14 allows attackers to execute privileged action by hijacking and modifying the intent.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-25352"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-668",
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-03-25T17:15:00Z",
    "severity": "HIGH"
  },
  "details": "Using PendingIntent with implicit intent in Bixby Voice prior to version 3.0.52.14 allows attackers to execute privileged action by hijacking and modifying the intent.",
  "id": "GHSA-xfcw-6c56-rp9p",
  "modified": "2022-08-13T00:00:33Z",
  "published": "2022-05-24T17:45:24Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-25352"
    },
    {
      "type": "WEB",
      "url": "https://security.samsungmobile.com"
    },
    {
      "type": "WEB",
      "url": "https://security.samsungmobile.com/serviceWeb.smsb"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-XFF3-5C9P-2MR4

Vulnerability from github – Published: 2026-04-24 15:43 – Updated: 2026-05-13 13:37
VLAI
Summary
New API: Stripe Webhook Signature Bypass via Empty Secret Enables Unlimited Quota Fraud
Details

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.goStripeWebhook(), sessionCompleted()
  • model/topup.goRecharge(), RechargeCreem(), RechargeWaffo()
  • controller/topup.goEpayNotify()
  • controller/topup_creem.goCreemAdaptor.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):

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:

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":

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

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

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

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

// 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:

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

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/QuantumNous/new-api"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.12.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-41432"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-1188",
      "CWE-345",
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-24T15:43:25Z",
    "nvd_published_at": "2026-05-08T23:16:35Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nA 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:\n\n1. The Stripe webhook endpoint does not reject requests when `StripeWebhookSecret` is empty (the default).\n2. When the HMAC secret is empty, any attacker can compute valid webhook signatures, effectively **bypassing signature verification entirely**.\n3. The `Recharge` function does not validate that the order\u0027s `PaymentMethod` matches the callback source, enabling **cross-gateway exploitation** \u2014 an order created via any payment method (e.g., Epay) can be fulfilled through a forged Stripe webhook.\n\n## Affected Components\n\n- `controller/topup_stripe.go` \u2014 `StripeWebhook()`, `sessionCompleted()`\n- `model/topup.go` \u2014 `Recharge()`, `RechargeCreem()`, `RechargeWaffo()`\n- `controller/topup.go` \u2014 `EpayNotify()`\n- `controller/topup_creem.go` \u2014 `CreemAdaptor.RequestPay()` (missing `PaymentMethod` field)\n- `router/api-router.go` \u2014 webhook route registered without any guard\n\n## CWE Classification\n\n- **CWE-345**: Insufficient Verification of Data Authenticity\n- **CWE-1188**: Initialization with an Insecure Default (empty webhook secret)\n- **CWE-863**: Incorrect Authorization (cross-gateway order fulfillment)\n\n## Vulnerability Details\n\n### Flaw 1: Empty Webhook Secret Bypasses Signature Verification\n\nThe `StripeWebhookSecret` setting defaults to an empty string `\"\"`. The Stripe Go SDK (`webhook.ConstructEventWithOptions`) does **not** reject empty secrets \u2014 it computes `HMAC-SHA256` with an empty key, producing a deterministic and publicly computable signature.\n\n**Vulnerable code** (`controller/topup_stripe.go`):\n```go\nfunc StripeWebhook(c *gin.Context) {\n    // No check for empty StripeWebhookSecret\n    payload, _ := io.ReadAll(c.Request.Body)\n    signature := c.GetHeader(\"Stripe-Signature\")\n    endpointSecret := setting.StripeWebhookSecret // defaults to \"\"\n    event, err := webhook.ConstructEventWithOptions(payload, signature, endpointSecret, ...)\n    // When secret is \"\", attacker can compute valid HMAC with the same empty key\n}\n```\n\nThe webhook route is unconditionally registered with **no authentication middleware and no rate limiting**:\n```go\napiRouter.POST(\"/stripe/webhook\", controller.StripeWebhook)\n```\n\n### Flaw 2: Missing `payment_status` Verification\n\nThe `sessionCompleted` handler only checks `status == \"complete\"` but does **not** verify `payment_status == \"paid\"`. Stripe\u0027s `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.\n\nAdditionally, `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.\n\n### Flaw 3: Cross-Gateway Order Fulfillment (No PaymentMethod Validation)\n\nThe `model.Recharge()` function (called by the Stripe webhook) looks up orders solely by `trade_no` and does **not** validate that the order\u0027s `PaymentMethod` is `\"stripe\"`:\n\n```go\nfunc Recharge(referenceId string, customerId string) (err error) {\n    // Finds ANY pending order by trade_no, regardless of PaymentMethod\n    tx.Where(\"trade_no = ?\", referenceId).First(topUp)\n    if topUp.Status != \"pending\" { return }\n    // Credits quota without checking topUp.PaymentMethod\n    quota = topUp.Money * QuotaPerUnit\n    tx.Model(\u0026User{}).Update(\"quota\", gorm.Expr(\"quota + ?\", quota))\n}\n```\n\nThis allows an attacker to create orders through **any** configured payment gateway (Epay, Creem, Waffo) and then complete them via a forged Stripe webhook \u2014 even if Stripe itself was never configured.\n\n## Attack Scenario\n\n**Prerequisites**: Any payment method is configured (e.g., Epay) + `StripeWebhookSecret` is empty (default).\n\n1. Attacker registers a user account.\n2. Attacker calls `POST /api/user/pay` to create an Epay top-up order (e.g., `amount=10000`). The order is stored with `status=pending`.\n3. Attacker queries `GET /api/user/topup/self` to retrieve the `trade_no` of the pending order.\n4. Attacker computes `HMAC-SHA256` with an empty key over a crafted `checkout.session.completed` payload containing the stolen `trade_no` as `client_reference_id`.\n5. Attacker sends `POST /api/stripe/webhook` with the forged payload and signature header.\n6. 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.\n7. Attacker repeats steps 2\u20136 indefinitely for unlimited credits.\n\n**Proof of concept** (pseudocode):\n```python\nimport hmac, hashlib, time, json, requests\n\ntimestamp = int(time.time())\npayload = json.dumps({\n    \"type\": \"checkout.session.completed\",\n    \"data\": {\n        \"object\": {\n            \"client_reference_id\": \"\u003ctrade_no from step 3\u003e\",\n            \"status\": \"complete\",\n            \"payment_status\": \"paid\",\n            \"customer\": \"cus_fake\",\n            \"amount_total\": \"0\",\n            \"currency\": \"usd\"\n        }\n    }\n})\n# Empty secret = publicly computable signature\nsig = hmac.new(b\"\", f\"{timestamp}.{payload}\".encode(), hashlib.sha256).hexdigest()\nheader = f\"t={timestamp},v1={sig}\"\n\nrequests.post(\"https://target/api/stripe/webhook\",\n    data=payload,\n    headers={\"Stripe-Signature\": header, \"Content-Type\": \"application/json\"})\n```\n\n## Remediation\n\n### Fix 1: Reject webhooks when secret is empty\n```go\nfunc StripeWebhook(c *gin.Context) {\n    if setting.StripeWebhookSecret == \"\" {\n        c.AbortWithStatus(http.StatusForbidden)\n        return\n    }\n    // ... existing logic\n}\n```\n\n### Fix 2: Verify `payment_status` and handle async payment events\n```go\nfunc sessionCompleted(event stripe.Event) {\n    // ... existing status check ...\n    paymentStatus := event.GetObjectValue(\"payment_status\")\n    if paymentStatus != \"paid\" {\n        return // Wait for async_payment_succeeded event\n    }\n    fulfillOrder(event, referenceId, customerId)\n}\n```\n\nAdd handlers for `checkout.session.async_payment_succeeded` and `checkout.session.async_payment_failed`.\n\n### Fix 3: Validate PaymentMethod in all recharge functions\n```go\n// In model.Recharge (Stripe):\nif topUp.PaymentMethod != \"stripe\" {\n    return ErrPaymentMethodMismatch\n}\n\n// In model.RechargeCreem:\nif topUp.PaymentMethod != \"creem\" {\n    return ErrPaymentMethodMismatch\n}\n\n// In model.RechargeWaffo:\nif topUp.PaymentMethod != \"waffo\" {\n    return ErrPaymentMethodMismatch\n}\n\n// In controller.EpayNotify:\nif topUp.PaymentMethod == \"stripe\" || topUp.PaymentMethod == \"creem\" || topUp.PaymentMethod == \"waffo\" {\n    return // reject cross-gateway fulfillment\n}\n```\n\n### Additional fix: Set PaymentMethod on Creem order creation\nThe Creem order creation was missing the `PaymentMethod` field entirely:\n```go\ntopUp := \u0026model.TopUp{\n    // ...\n    PaymentMethod: \"creem\", // was missing\n}\n```\n\n## Patched Versions\n\n- **v0.12.10** \u2014 includes all three fixes described above.\n\nAll users are strongly encouraged to upgrade immediately.\n\n## Workaround (for users unable to upgrade immediately)\n\nIf users cannot upgrade to v0.12.10 right away, apply **all** of the following mitigations:\n\n1. **Set `StripeWebhookSecret` to any non-empty value.** Go to the admin panel \u2192 Payment \u2192 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 \u2014 any non-empty value will prevent the empty-key HMAC forgery. **This is the single most important step** \u2014 it closes the primary attack vector. If Stripe payments are used in production, replace with the real secret from the project\u0027s [Stripe Dashboard \u2192 Webhooks](https://dashboard.stripe.com/webhooks) to ensure legitimate webhooks continue to work.\n\n2. **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`:\n   ```nginx\n   location = /api/stripe/webhook {\n       return 403;\n   }\n   ```\n\n\u003e **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.**\n\n## Impact\n\n- **Financial fraud**: Attacker obtains unlimited API quota without payment.\n- **Operator financial loss**: Fraudulent quota is consumed against upstream AI providers (OpenAI, Anthropic, Google, etc.), charged to the operator.\n- **Silent exploitation**: Fraudulent top-ups appear as normal successful transactions in system logs, making detection difficult.\n- **Wide exposure**: The default insecure configuration means virtually all deployments with any payment method enabled are vulnerable.\n\n## Timeline\n\n- **2025-04-15**: Vulnerability reported by [@ChangeYu0229](https://github.com/ChangeYu0229)\n- **2025-04-15**: Vulnerability confirmed and root cause analysis completed\n- **2025-04-15**: Fix developed and applied\n- **2025-04-15**: Patched in v0.12.10\n\n## Resources\n\n- [Stripe Webhook Signature Verification Docs](https://docs.stripe.com/webhooks#verify-official-libraries)\n- [Stripe Checkout Fulfillment Guide \u2014 Handle async payment methods](https://docs.stripe.com/checkout/fulfillment#async-payment-methods)\n- [CWE-345: Insufficient Verification of Data Authenticity](https://cwe.mitre.org/data/definitions/345.html)\n- [CWE-1188: Initialization with an Insecure Default](https://cwe.mitre.org/data/definitions/1188.html)",
  "id": "GHSA-xff3-5c9p-2mr4",
  "modified": "2026-05-13T13:37:29Z",
  "published": "2026-04-24T15:43:25Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/QuantumNous/new-api/security/advisories/GHSA-xff3-5c9p-2mr4"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-41432"
    },
    {
      "type": "WEB",
      "url": "https://docs.stripe.com/checkout/fulfillment#async-payment-methods"
    },
    {
      "type": "WEB",
      "url": "https://docs.stripe.com/webhooks#verify-official-libraries"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/QuantumNous/new-api"
    },
    {
      "type": "WEB",
      "url": "https://github.com/QuantumNous/new-api/releases/tag/v0.12.10"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L",
      "type": "CVSS_V3"
    }
  ],
  "summary": "New API: Stripe Webhook Signature Bypass via Empty Secret Enables Unlimited Quota Fraud"
}

GHSA-XFF9-CGJH-MVPP

Vulnerability from github – Published: 2022-05-24 17:40 – Updated: 2022-05-24 17:40
VLAI
Details

Archer before 6.9 P1 (6.9.0.1) contains an improper access control vulnerability in an API. A remote authenticated malicious administrative user can potentially exploit this vulnerability to gather information about the system, and may use this information in subsequent attacks.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2020-29538"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-01-29T07:15:00Z",
    "severity": "MODERATE"
  },
  "details": "Archer before 6.9 P1 (6.9.0.1) contains an improper access control vulnerability in an API. A remote authenticated malicious administrative user can potentially exploit this vulnerability to gather information about the system, and may use this information in subsequent attacks.",
  "id": "GHSA-xff9-cgjh-mvpp",
  "modified": "2022-05-24T17:40:35Z",
  "published": "2022-05-24T17:40:35Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2020-29538"
    },
    {
      "type": "WEB",
      "url": "https://community.rsa.com/docs/DOC-115223"
    },
    {
      "type": "WEB",
      "url": "https://www.rsa.com/en-us/company/vulnerability-response-policy"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-XFH7-PHR7-GR2X

Vulnerability from github – Published: 2026-03-06 18:45 – Updated: 2026-03-06 22:52
VLAI
Summary
parse-server's file creation and deletion bypasses `readOnlyMasterKey` write restriction
Details

Impact

The readOnlyMasterKey can be used to create and delete files via the Files API (POST /files/:filename, DELETE /files/:filename). This bypasses the read-only restriction which violates the access scope of the readOnlyMasterKey.

Any Parse Server deployment that uses readOnlyMasterKey and exposes the Files API is affected. An attacker with access to the readOnlyMasterKey can upload arbitrary files or delete existing files.

Patches

The fix adds permission checks to both the file upload and file delete handlers.

Workarounds

There is no workaround other than not using readOnlyMasterKey, or restricting network access to the Files API endpoints.

References

  • GitHub security advisory: https://github.com/parse-community/parse-server/security/advisories/GHSA-xfh7-phr7-gr2x
  • Fix for Parse Server 9: https://github.com/parse-community/parse-server/releases/tag/9.5.0-alpha.3
  • Fix for Parse Server 8: https://github.com/parse-community/parse-server/releases/tag/8.6.5
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "parse-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "9.0.0"
            },
            {
              "fixed": "9.5.0-alpha.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "parse-server"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "8.6.5"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-30228"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-06T18:45:36Z",
    "nvd_published_at": "2026-03-06T21:16:16Z",
    "severity": "MODERATE"
  },
  "details": "### Impact\n\nThe `readOnlyMasterKey` can be used to create and delete files via the Files API (`POST /files/:filename`, `DELETE /files/:filename`). This bypasses the read-only restriction which violates the access scope of the `readOnlyMasterKey`.\n\nAny Parse Server deployment that uses `readOnlyMasterKey` and exposes the Files API is affected. An attacker with access to the `readOnlyMasterKey` can upload arbitrary files or delete existing files.\n\n### Patches\n\nThe fix adds permission checks to both the file upload and file delete handlers.\n\n### Workarounds\n\nThere is no workaround other than not using `readOnlyMasterKey`, or restricting network access to the Files API endpoints.\n\n### References\n \n- GitHub security advisory: https://github.com/parse-community/parse-server/security/advisories/GHSA-xfh7-phr7-gr2x\n- Fix for Parse Server 9: https://github.com/parse-community/parse-server/releases/tag/9.5.0-alpha.3\n- Fix for Parse Server 8: https://github.com/parse-community/parse-server/releases/tag/8.6.5",
  "id": "GHSA-xfh7-phr7-gr2x",
  "modified": "2026-03-06T22:52:58Z",
  "published": "2026-03-06T18:45:36Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/parse-community/parse-server/security/advisories/GHSA-xfh7-phr7-gr2x"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-30228"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/parse-community/parse-server"
    },
    {
      "type": "WEB",
      "url": "https://github.com/parse-community/parse-server/releases/tag/8.6.5"
    },
    {
      "type": "WEB",
      "url": "https://github.com/parse-community/parse-server/releases/tag/9.5.0-alpha.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "parse-server\u0027s file creation and deletion bypasses `readOnlyMasterKey` write restriction"
}

GHSA-XFQ3-QJ7J-4565

Vulnerability from github – Published: 2025-12-26 03:30 – Updated: 2025-12-26 19:12
VLAI
Summary
Gitea mishandles access to a private resource upon receiving an API token with scope limited to public resources
Details

Gitea before 1.22.3 mishandles access to a private resource upon receiving an API token with scope limited to public resources.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "code.gitea.io/gitea"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.22.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-68941"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-863"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-12-26T19:12:54Z",
    "nvd_published_at": "2025-12-26T03:15:50Z",
    "severity": "MODERATE"
  },
  "details": "Gitea before 1.22.3 mishandles access to a private resource upon receiving an API token with scope limited to public resources.",
  "id": "GHSA-xfq3-qj7j-4565",
  "modified": "2025-12-26T19:12:54Z",
  "published": "2025-12-26T03:30:15Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-68941"
    },
    {
      "type": "WEB",
      "url": "https://github.com/go-gitea/gitea/pull/32218"
    },
    {
      "type": "WEB",
      "url": "https://blog.gitea.com/release-of-1.22.3"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/go-gitea/gitea"
    },
    {
      "type": "WEB",
      "url": "https://github.com/go-gitea/gitea/releases/tag/v1.22.3"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Gitea mishandles access to a private resource upon receiving an API token with scope limited to public resources"
}

Mitigation
Architecture and Design
  • Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries.
  • Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
Mitigation
Architecture and Design

Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].

Mitigation MIT-4.4
Architecture and Design

Strategy: Libraries or Frameworks

  • Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.
  • For example, consider using authorization frameworks such as the JAAS Authorization Framework [REF-233] and the OWASP ESAPI Access Control feature [REF-45].
Mitigation
Architecture and Design
  • For web applications, make sure that the access control mechanism is enforced correctly at the server side on every page. Users should not be able to access any unauthorized functionality or information by simply requesting direct access to that page.
  • One way to do this is to ensure that all pages containing sensitive information are not cached, and that all such pages restrict access to requests that are accompanied by an active and authenticated session token associated with a user who has the required permissions to access that page.
Mitigation
System Configuration Installation

Use the access control capabilities of your operating system and server environment and define your access control lists accordingly. Use a "default deny" policy when defining these ACLs.

No CAPEC attack patterns related to this CWE.