A public endpoint needs an explicit public response model, not the raw stored object.
The public config returned the private object.
A public chatbot configuration endpoint exists so an embedded widget can render without authentication. That makes its response a public surface. The security property is that the response carries only fields intended for the public: it must not leak the internal configuration a builder stored in the flow.
The upstream advisory records sensitive-data exposure for versions up to 3.0.13. The endpoint returned the chatflow’s stored flow data, which can contain credential fields, so an unauthenticated caller with a chatflow identifier could read secrets.
The raw flow data left through a public route.
A public route mapped the chatflow identifier to the configuration handler with no authentication. The service loaded the chatflow by identifier and returned an object that spread the parsed chatbot config together with the stored flow data. It removed a pair of origin fields but did not strip the credential-bearing content of the flow.
Inside that flow data were password-type node fields—API keys held by integration nodes—along with authorization headers configured on HTTP request nodes and internal endpoint and webhook URLs. Because the caller needs only a chatflow identifier, which appears in embedded widgets, referrer headers and logs, the identifier functioned as the entire access boundary.
- Public route by id
No authentication is required.
- Load the chatflow
The full stored object is fetched.
- Return raw flow data
Credential fields travel out unchanged.
- Public route by id
The same public entry point.
- Load the chatflow
The stored object is fetched.
- Sanitize before returning
Credential fields are stripped from the response.
Conceptual control flow reconstructed from the upstream source. It is not a captured request or a TraceMint execution trace.
Sanitize the flow data for the public endpoint.
The patched release runs the flow data through a sanitizer before returning it from the public configuration handler. The public response therefore carries a reduced view of the flow rather than its raw, credential-bearing form.
The fix defines the public shape explicitly at the point of serialization. The endpoint still returns what a widget needs to render; it no longer returns the fields a builder used to authenticate to third-party services.
router.get(['/', '/:id'], chatflowsController.getSinglePublicChatbotConfig)const dbResponse = await appServer.AppDataSource.getRepository(ChatFlow).findOneBy({ id: chatflowId})return { ...parsedConfig, uploads: uploadsConfig, flowData: dbResponse.flowData, isTTSEnabled }flowData: sanitizeFlowDataForPublicEndpoint(dbResponse.flowData),Selected upstream lines; indentation normalized. Links include surrounding code at immutable revisions.
An identifier is not a secret.
The upstream advisory rates the issue High and identifies 3.1.0 as patched. The access prerequisite is only a chatflow identifier, which is not confidential: it appears in embedded widgets, referrer headers and logs. The exposed material—API keys, authorization headers and internal URLs—is credential-grade, which is what raises the severity.
- A public endpoint
- The configuration route requires no authentication.
- A known chatflow id
- The identifier is visible in widgets, referrers and logs.
- Credential-grade fields
- Node API keys and authorization headers travelled in the response.
Inspect the serialized bytes for secrets.
A regression check builds a chatflow with a node that stores a credential, then requests the public configuration without authentication and inspects the response body for that value. A patched build should return a rendering view with the credential fields removed. Compare the serialized content against an allowlist of intended public fields. The scenarios below are suggested review checks, not reported TraceMint test results.
| Scenario | Expected boundary |
|---|---|
| Public config for a flow with credentials | The response omits API keys and authorization headers. |
| Public config for a flow with webhooks | Internal endpoint and webhook URLs are not exposed. |
| Fields a widget needs | Rendering configuration is still present and usable. |
| Serialized allowlist review | Only intended public fields appear in the body. |
Define the public shape, do not trust the label.
For reviewers, a field named like configuration can still carry credentials. Serialize an explicit allowlist of safe fields for any unauthenticated endpoint, and review the actual serialized content rather than the field’s name. Removing a couple of known-bad keys is weaker than defining what may leave.
The public advisory credits the TraceMint account as reporter, and the maintainers supplied the remediation. This study analyzes the public advisory and immutable source revisions; it does not claim sole discovery or access to any deployment.
Follow the evidence.
Public upstream records and immutable code revisions, reviewed 2026-09-22.
- Flowise security advisory
Impact, prerequisites, patched release and reporter credit.
- Public route before the fix
Immutable revision · f0c12941 · unauthenticated config route.
- Config service before the fix
Returns the raw flow data by identifier.
- Patched release source (3.1.0)
The patched release sanitizes the flow data for the public endpoint.
- Config service after the fix
Immutable revision · 378d3ec3 · sanitized flow data in the response.
Brief code excerpts from FlowiseAI/Flowise. Upstream license: Apache-2.0 with Commons Clause. All remediation described here is upstream work.
Read the original record
This case study analyzes an already-public advisory and upstream source. For the complete impact, remediation and credit record, see the Flowise security advisory.
Editorial publication is separate from disclosure. No private discovery timeline or method has been inferred.