Vulnerability
IDOR in GET/PATCH/DELETE /api/v1/flow/{flowid}
The readflow helper in src/backend/base/langflow/api/v1/flows.py branched on the AUTOLOGIN setting to decide whether to filter by userid. When AUTOLOGIN was False (i.e., authentication was enabled), neither branch enforced an ownership check — the query returned any flow matching the given UUID regardless of who owned it.
This exposed any authenticated user to:
- Read any other user's flow, including embedded plaintext API keys - Modify the logic of another user's AI agents - Delete flows belonging to other users
The vulnerability was introduced by the conditional logic that was meant to accommodate public/example flows (those with userid = NULL) under auto-login mode, but inadvertently left the authenticated path without an ownership filter.
---
Fix (PR #8956)
The fix removes the AUTOLOGIN conditional entirely and unconditionally scopes the query to the requesting user:
diff - authsettings = settingsservice.authsettings - stmt = select(Flow).where(Flow.id == flowid) - if authsettings.AUTOLOGIN: - stmt = stmt.where( - (Flow.userid == userid) | (Flow.userid == None) # noqa: E711 - ) + stmt = select(Flow).where(Flow.id == flowid).where(Flow.userid == userid)
All three operations — read, update, and delete — route through readflow, so the single change covers the full attack surface. A cross-user isolation test (testreadflowsuserisolation) was added to prevent regression.
---
Acknowledgements
Langflow thanks the security researcher who responsibly disclosed this vulnerability:
- @chximn-dt