GHSA-rwrp-9823-p2xq: Flowise: credential API leaks plaintext DB/cloud secrets
GHSA-rwrp-9823-p2xqMEDIUMFlowise's credential retrieval endpoint decrypts stored secrets and returns them in full plaintext for any field not explicitly typed as `password` in its schema — meaning MongoDB, PostgreSQL and Redis connection strings, AWS access keys, and full Google Cloud service account JSON with RSA private keys are all exposed verbatim to any authenticated user holding the `credentials:view` permission. This is a low-complexity, no-exploit-tooling-required flaw (CVSS 6.5, AV:N/AC:L/PR:L/UI:N/C:H) that turns a legitimate low-privilege workspace role into full credential harvesting across every connected database and cloud service the agent platform touches, which matters because Flowise agent workflows commonly wire in production data stores and cloud identities. There's no evidence of a public exploit, scanner template, or CISA KEV listing, and EPSS data is unavailable, so this reads as opportunistic-insider risk rather than internet-scanned mass exploitation — the real exposure is in multi-tenant or multi-user Flowise deployments where trust boundaries between workspace members matter. Upgrade to Flowise 3.1.3 immediately, then treat any credential previously visible through `GET /api/v1/credentials/:id` as compromised and rotate it (DB passwords, AWS keys, GCP service account keys), and audit historical access logs for that endpoint to identify who retrieved which credentials.
What is the risk?
Medium severity per CVSS (6.5, confidentiality-only impact) but the practical blast radius is high in any multi-user or multi-tenant Flowise deployment: exploitation requires only a valid low-privilege account with `credentials:view`, no special AI/ML knowledge, and a single unauthenticated-style GET request once logged in — this is trivial to exploit for anyone who already has a foothold. There is no public PoC weaponization, no Nuclei template, and it's not in CISA KEV, so opportunistic internet-wide exploitation is unlikely; the primary risk vector is malicious or compromised insiders, over-permissioned service accounts, or SaaS/managed-Flowise offerings where customers share a platform. The confirmed exposure of RSA private keys inside Google service account JSON and raw database connection strings makes any successful exploitation high-consequence despite the CVSS score understating downstream blast radius (lateral movement into databases and cloud tenants).
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| Flowise | npm | <= 3.1.2 | 3.1.3 |
Do you use Flowise? You're affected.
How severe is it?
What is the attack surface?
What should I do?
1 step1) Upgrade to Flowise >= 3.1.3 immediately, which fixes the redaction logic. 2) Treat every credential ever retrieved via
GET /api/v1/credentials/:idprior to patching as potentially compromised — rotate database passwords/connection strings, regenerate AWS access keys, and reissue Google service account keys. 3) Audit access logs / API request logs for calls to the credentials endpoint to identify which users retrieved which secrets. 4) Tighten thecredentials:viewpermission to the minimum necessary set of users until rotation is complete. 5) After patching, verify via a test credential of each affected type (mongoDBUrlApi, googleVertexAuth, postgresUrl, redisCacheUrlApi, awsApi, etc.) thatplainDataObjnow returns redacted values, not just password-typed fields.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is GHSA-rwrp-9823-p2xq?
Flowise's credential retrieval endpoint decrypts stored secrets and returns them in full plaintext for any field not explicitly typed as `password` in its schema — meaning MongoDB, PostgreSQL and Redis connection strings, AWS access keys, and full Google Cloud service account JSON with RSA private keys are all exposed verbatim to any authenticated user holding the `credentials:view` permission. This is a low-complexity, no-exploit-tooling-required flaw (CVSS 6.5, AV:N/AC:L/PR:L/UI:N/C:H) that turns a legitimate low-privilege workspace role into full credential harvesting across every connected database and cloud service the agent platform touches, which matters because Flowise agent workflows commonly wire in production data stores and cloud identities. There's no evidence of a public exploit, scanner template, or CISA KEV listing, and EPSS data is unavailable, so this reads as opportunistic-insider risk rather than internet-scanned mass exploitation — the real exposure is in multi-tenant or multi-user Flowise deployments where trust boundaries between workspace members matter. Upgrade to Flowise 3.1.3 immediately, then treat any credential previously visible through `GET /api/v1/credentials/:id` as compromised and rotate it (DB passwords, AWS keys, GCP service account keys), and audit historical access logs for that endpoint to identify who retrieved which credentials.
Is GHSA-rwrp-9823-p2xq actively exploited?
No confirmed active exploitation of GHSA-rwrp-9823-p2xq has been reported, but organizations should still patch proactively.
How to fix GHSA-rwrp-9823-p2xq?
1) Upgrade to Flowise >= 3.1.3 immediately, which fixes the redaction logic. 2) Treat every credential ever retrieved via `GET /api/v1/credentials/:id` prior to patching as potentially compromised — rotate database passwords/connection strings, regenerate AWS access keys, and reissue Google service account keys. 3) Audit access logs / API request logs for calls to the credentials endpoint to identify which users retrieved which secrets. 4) Tighten the `credentials:view` permission to the minimum necessary set of users until rotation is complete. 5) After patching, verify via a test credential of each affected type (mongoDBUrlApi, googleVertexAuth, postgresUrl, redisCacheUrlApi, awsApi, etc.) that `plainDataObj` now returns redacted values, not just password-typed fields.
What systems are affected by GHSA-rwrp-9823-p2xq?
This vulnerability affects the following AI/ML architecture patterns: agent frameworks, RAG pipelines, credential/secrets management, multi-tenant SaaS deployments.
What is the CVSS score for GHSA-rwrp-9823-p2xq?
GHSA-rwrp-9823-p2xq has a CVSS v3.1 base score of 6.5 (MEDIUM).
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0012Valid AccountsAML.T0055Unsecured CredentialsAML.T0083Credentials from AI Agent ConfigurationCompliance Controls Affected
What are the technical details?
Original Advisory
## Summary The `GET /api/v1/credentials/:id` endpoint decrypts stored credential data and returns it in the `plainDataObj` field of the API response. While a `redactCredentialWithPasswordType()` function masks fields defined with `type: 'password'` in their component schema, many credential types store highly sensitive data (database connection URLs with embedded passwords, Google service account JSON with RSA private keys, AWS access keys) in fields defined as `type: 'string'`. These string-type fields are returned in **full plaintext** without any redaction. Any authenticated user with `credentials:view` permission can retrieve the raw secrets of any credential in their workspace by calling this endpoint. ## Vulnerable Code ### Service Layer **`packages/server/src/services/credentials/index.ts`**, `getCredentialById()` (line 127): At line 138, the credential's encrypted data is decrypted: ```typescript const decryptedCredentialData = await decryptCredentialData( credential.encryptedData, credential.credentialName, appServer.nodesPool.componentCredentials ) ``` At lines 143-146, the decrypted data is attached to the response as `plainDataObj`: ```typescript const returnCredential: ICredentialReturnResponse = { ...credential, plainDataObj: decryptedCredentialData // <-- decrypted secrets in response } ``` At line 147, only `encryptedData` is stripped, leaving `plainDataObj` intact: ```typescript const dbResponse: any = omit(returnCredential, ['encryptedData']) ``` ### Incomplete Redaction **`packages/server/src/utils/index.ts`**, `redactCredentialWithPasswordType()` (line 1697): ```typescript export const redactCredentialWithPasswordType = ( componentCredentialName: string, decryptedCredentialObj: ICredentialDataDecrypted, componentCredentials: IComponentCredentials ): ICredentialDataDecrypted => { const plainDataObj = cloneDeep(decryptedCredentialObj) for (const cred in plainDataObj) { const inputParam = componentCredentials[componentCredentialName].inputs?.find( (inp) => inp.type === 'password' && inp.name === cred // <-- only 'password' type ) if (inputParam) { plainDataObj[cred] = REDACTED_CREDENTIAL_VALUE } } return plainDataObj } ``` This function **only** redacts fields where `inp.type === 'password'`. Fields with `type: 'string'` are returned verbatim, even when they contain secrets. ### Credential Definitions Storing Secrets in String-Type Fields | Credential | Field | Type | Contains | |---|---|---|---| | `mongoDBUrlApi` | `mongoDBConnectUrl` | `string` | `mongodb+srv://user:password@host/db` | | `googleVertexAuth` | `googleApplicationCredential` | `string` | Full service account JSON with RSA private key | | `postgresUrl` | `postgresUrl` | `string` | `postgresql://user:password@host/db` | | `redisCacheUrlApi` | `redisUrl` | `string` | `redis://user:password@host:port` | | `awsApi` | `awsKey` | `string` | AWS Access Key ID | | `langfuseApi` | `langFusePublicKey` | `string` | Langfuse API public key | | `httpBasicAuth` | `basicAuthUsername` | `string` | HTTP Basic Auth username | There are 60+ credential definitions in `packages/components/credentials/`, many with sensitive string-type fields. ## Proof of Concept ### Environment - Flowise v3.0.13 (`flowiseai/flowise:latest` Docker image) - Authenticated as admin user via enterprise auth ### Steps to Reproduce 1. Start Flowise and log in as any user with `credentials:view` permission. 2. Create a MongoDB credential with a connection URL containing embedded credentials: ```bash curl -X POST "http://TARGET:3000/api/v1/credentials" \ -H "Content-Type: application/json" \ -H "x-request-from: internal" \ -H "Cookie: token=<jwt-token>" \ -d '{ "name": "MongoDB Production", "credentialName": "mongoDBUrlApi", "plainDataObj": { "mongoDBConnectUrl": "mongodb+srv://admin:SuperSecretPassword123@cluster0.abc123.mongodb.net/mydb" } }' ``` 3. Retrieve the credential by ID: ```bash curl -X GET "http://TARGET:3000/api/v1/credentials/<credential-id>" \ -H "x-request-from: internal" \ -H "Cookie: token=<jwt-token>" ``` ### Observed Result The API returns the MongoDB connection URL in **full plaintext**, including the embedded password: ```json { "id": "e9543cad-8c0c-422e-9990-090c3b1dc3ab", "name": "MongoDB Production", "credentialName": "mongoDBUrlApi", "createdDate": "2026-02-07T17:35:29.000Z", "updatedDate": "2026-02-07T17:35:29.000Z", "plainDataObj": { "mongoDBConnectUrl": "mongodb+srv://admin:SuperSecretPassword123@cluster0.abc123.mongodb.net/mydb" } } ``` The same test with a Google Vertex Auth credential returned the **complete service account JSON including the RSA private key** in plaintext: ```json { "id": "f7768444-a4fc-4fa3-8e5e-d0d4df89fb56", "name": "Google Vertex Auth", "credentialName": "googleVertexAuth", "plainDataObj": { "googleApplicationCredential": "{\"type\":\"service_account\",\"private_key\":\"-----BEGIN RSA PRIVATE KEY-----\\nMIIEpAIBAAKCAQEA0Z3VS5JJcds3xfn/ygWep4PAtGoL3VBpFe97XRQFQB\\n-----END RSA PRIVATE KEY-----\\n\",\"client_email\":\"mybot@my-project-123.iam.gserviceaccount.com\"}", "projectID": "my-project-123" } } ``` For comparison, an OpenAI API key (where the field is typed as `password`) was **correctly redacted**: ```json { "plainDataObj": { "openAIApiKey": "_FLOWISE_BLANK_07167752-1a71-43b1-" } } ``` This confirms the redaction is only applied to `password`-type fields, leaving `string`-type fields fully exposed. ## Impact - **Database credential theft**: MongoDB, PostgreSQL, Redis, MySQL connection URLs with embedded passwords are returned in full plaintext. An attacker can use these to directly access production databases. - **Cloud service account compromise**: Google service account JSON with RSA private keys is returned in plaintext, enabling full impersonation of the service account across Google Cloud. - **AWS key exposure**: AWS Access Key IDs stored in `string`-type fields are exposed, enabling enumeration of active AWS credentials. - **Lateral movement**: Stolen credentials enable pivoting from the Flowise instance to connected cloud services, databases, and APIs. - **Multi-user workspace risk**: In multi-user deployments, any user with `credentials:view` permission can harvest all workspace credentials via the API. ## Remediation 1. Apply `redactCredentialWithPasswordType()` to **all** sensitive credential fields, not just those typed as `password`. Any field containing secrets (connection strings, JSON credentials, access keys) should be redacted. 2. Consider never returning `plainDataObj` in API responses. The UI should use masked previews (e.g., `mongodb+srv://admin:****@cluster0...`) instead of full values. 3. Re-type sensitive credential fields from `string` to `password` in component credential definitions to ensure they are covered by the existing redaction logic. 4. Add a separate `secret: true` flag to credential field definitions to explicitly mark sensitive fields regardless of their input type.
Exploitation Scenario
A contractor or low-privilege employee is granted a Flowise workspace account with `credentials:view` for legitimate workflow-building purposes. Instead of using it only to configure agent nodes, they call `GET /api/v1/credentials/<id>` directly against every credential ID in the workspace, harvesting the MongoDB production connection string (with embedded password) and a Google Vertex AI service account's full RSA private key in plaintext. Using the MongoDB URL, they connect directly to the production database from outside the platform; using the GCP service account key, they authenticate to Google Cloud APIs and impersonate the service account across any GCP resources it has IAM access to — fully bypassing Flowise's intended access boundary and pivoting from a workflow-builder role to production infrastructure compromise.
Weaknesses (CWE)
CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
- [Architecture and Design] Compartmentalize the system to have "safe" areas where trust boundaries can be unambiguously drawn. Do not allow sensitive data to go outside of the trust boundary and always be careful when interfacing with a compartment outside of the safe area. Ensure that appropriate compartmentalization is built into the system design, and the compartmentalization allows for and reinforces privilege separation functionality. Architects and designers should rely on the principle of least privilege to decide the appropriate time to use privileges and the time to drop privileges.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:NReferences
Timeline
Related Vulnerabilities
CVE-2025-7133810.0Flowise: unauthenticated file write enables RCE
Same package: flowiseCVE-2025-5952810.0Flowise: Unauthenticated RCE via MCP config injection
Same package: flowiseCVE-2025-619139.9Flowise: path traversal in file tools leads to RCE
Same package: flowiseCVE-2026-409339.9Flowise: RCE via MCP stdio command injection
Same package: flowiseCVE-2026-464429.9Flowise: sandbox escape enables authenticated RCE
Same package: flowise