CVE-2026-70476 Overview
CVE-2026-70476 is a broken access control vulnerability [CWE-284] in Flowise, a drag-and-drop interface for building large language model workflows. Versions prior to 3.1.3 expose organization billing endpoints that accept attacker-controlled Stripe subscriptionId values without verifying tenant ownership. An authenticated attacker can invoke Stripe subscription operations against other tenants, altering subscription plans or seat quantities. The result is financial impact and service disruption for victim organizations. The issue is fixed in Flowise 3.1.3.
Critical Impact
Any authenticated Flowise user can manipulate another tenant's Stripe subscription, changing billing plans or seat counts and disrupting service across organizations sharing the deployment.
Affected Products
- FlowiseAI Flowise versions prior to 3.1.3
- Deployments using enterprise organization billing routes in packages/server/src/enterprise/routes/organization.route.ts
- Deployments using organization controllers in packages/server/src/enterprise/controllers/organization.controller.ts
Discovery Timeline
- 2026-08-04 - CVE-2026-70476 published to NVD
- 2026-08-05 - Last updated in NVD database
- Fix released - Flowise 3.1.3 published on GitHub with the tenant guard patch
Technical Details for CVE-2026-70476
Vulnerability Analysis
The vulnerability lives in Flowise's enterprise organization billing surface. Several routes in organization.route.ts accept a Stripe subscriptionId parameter from the client. The corresponding handlers in organization.controller.ts pass that identifier directly to Stripe API calls. The server never checks that the supplied subscriptionId belongs to the authenticated user's organization.
Because the identifier is trusted implicitly, an authenticated attacker on one tenant can supply another tenant's subscriptionId. Flowise then executes the requested Stripe operation against the victim's subscription. Attackers can change subscription plans, adjust seat counts, or otherwise mutate billing state. The outcome is direct financial impact and denial of service through disrupted licensing.
This is a classic missing-authorization pattern in a multi-tenant SaaS control plane, and it maps cleanly to [CWE-284: Improper Access Control].
Root Cause
The root cause is the absence of a tenant-scoped authorization check between the session context and the requested Stripe resource. The handlers relied on authentication alone and never bound subscriptionId to the caller's organization record.
Attack Vector
Exploitation requires an authenticated session on the Flowise instance and network access to the billing endpoints. The attacker submits a normal billing request but substitutes a subscriptionId observed or enumerated from another tenant. No user interaction on the victim side is required.
// Patch: packages/server/src/enterprise/controllers/organization.controller.ts
import { GeneralErrorMessage } from '../../utils/constants'
import { OrganizationUserService } from '../services/organization-user.service'
import { getCurrentUsage } from '../../utils/quotaUsage'
+import { assertStripeIdMatchesSession } from '../utils/tenantRequestGuards'
export class OrganizationController {
public async create(req: Request, res: Response, next: NextFunction) {
// Source: https://github.com/FlowiseAI/Flowise/commit/4d7899d02ca370a5510406be5c91483085a412f9
// Patch: packages/server/src/enterprise/utils/tenantRequestGuards.ts
throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN)
}
+export function assertStripeIdMatchesSession(requestedId: string, activeId: string | undefined): void {
+ if (!activeId || requestedId !== activeId) {
+ throw new InternalFlowiseError(StatusCodes.FORBIDDEN, GeneralErrorMessage.FORBIDDEN)
+ }
+}
+
export function userMayManageOrgUsers(user: LoggedInUser): boolean {
return user.isOrganizationAdmin === true || (user.permissions?.includes('users:manage') ?? false)
}
// Source: https://github.com/FlowiseAI/Flowise/commit/4d7899d02ca370a5510406be5c91483085a412f9
The fix introduces assertStripeIdMatchesSession, which rejects any request whose subscriptionId does not match the active session's bound identifier.
Detection Methods for CVE-2026-70476
Indicators of Compromise
- Requests to Flowise organization billing endpoints where the subscriptionId parameter does not match the caller's organization record.
- Unexpected Stripe webhook events (customer.subscription.updated, seat quantity changes) that do not correlate with legitimate admin activity in Flowise audit logs.
- Authenticated users generating billing API calls that reference multiple distinct subscriptionId values within a short window.
Detection Strategies
- Correlate Flowise application logs with Stripe API activity to flag subscription changes not initiated by an organization admin.
- Alert on HTTP requests to routes defined in packages/server/src/enterprise/routes/organization.route.ts where the response is 200 but the target subscriptionId differs from the session tenant.
- Baseline normal billing operations per tenant and alert on cross-tenant identifier reuse.
Monitoring Recommendations
- Enable verbose logging on all enterprise organization routes and forward logs to a centralized analytics platform.
- Monitor Stripe dashboards for unexpected plan changes or seat adjustments, especially outside change windows.
- Track the Flowise version deployed in every environment and alert when instances remain below 3.1.3.
How to Mitigate CVE-2026-70476
Immediate Actions Required
- Upgrade all Flowise deployments to version 3.1.3 or later without delay.
- Audit recent Stripe subscription changes and reconcile them against authorized administrator activity in Flowise.
- Rotate any exposed Stripe API keys if unauthorized billing modifications are confirmed.
Patch Information
The fix is delivered in Flowise 3.1.3. The patch adds an assertStripeIdMatchesSession guard invoked by the organization controller before any Stripe operation. Review the GitHub Security Advisory GHSA-gmmw-qg98-6j6p, the GitHub Pull Request Discussion, the GitHub Commit Changes, and the GitHub Release Version 3.1.3 for full remediation detail.
Workarounds
- If upgrading immediately is not possible, restrict access to enterprise organization billing routes at the reverse proxy or API gateway layer to trusted administrators only.
- Temporarily disable self-service Stripe subscription management in Flowise and require out-of-band billing operations until the patch is applied.
- Enforce strict per-tenant network or identity segmentation so authenticated users cannot reach billing endpoints for other organizations.
# Example: block enterprise billing routes at an nginx reverse proxy
# until Flowise is upgraded to 3.1.3
location ~ ^/api/v1/organizations/.*/subscription {
allow 10.0.0.0/24; # trusted admin network
deny all;
proxy_pass http://flowise_upstream;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

