Langflow: Authenticated Users Can Read, Modify, and Delete Any Flow via Missing Ownership CheckGHSA-8c4j-f57c-35cf
Fix: langflow-ai/langflow#8956GHSA-8c4j-f57c-35cf is a CWE-639 vulnerability in langflow. A fix is available for langflow — see the affected versions and patch details below.
Exploitation Status
No confirmed exploitation observed yet
- A successful exploit gives an attacker total control of the affected component, not partial access.
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for GHSA-8c4j-f57c-35cf.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
Real-World Exposure
langflow🐍langflow-baseReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Vulnerability
IDOR in GET/PATCH/DELETE /api/v1/flow/{flow_id}
The _read_flow helper in src/backend/base/langflow/api/v1/flows.py branched on the AUTO_LOGIN setting to decide whether to filter by user_id. When AUTO_LOGIN 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 user_id = NULL) under auto-login mode, but inadvertently left the authenticated path without an ownership filter.
Fix (PR #8956)
The fix removes the AUTO_LOGIN conditional entirely and unconditionally scopes the query to the requesting user:
- auth_settings = settings_service.auth_settings
- stmt = select(Flow).where(Flow.id == flow_id)
- if auth_settings.AUTO_LOGIN:
- stmt = stmt.where(
- (Flow.user_id == user_id) | (Flow.user_id == None) # noqa: E711
- )
+ stmt = select(Flow).where(Flow.id == flow_id).where(Flow.user_id == user_id)
All three operations — read, update, and delete — route through _read_flow, so the single change covers the full attack surface. A cross-user isolation test (test_read_flows_user_isolation) was added to prevent regression.
Acknowledgements
Langflow thanks the security researcher who responsibly disclosed this vulnerability:
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | langflow | all versions | 1.5.1pip install --upgrade 'langflow==1.5.1' |
| 🐍PyPI | langflow-base | all versions | 0.5.1pip install --upgrade 'langflow-base==0.5.1' |
Affected Products
langflowlangflowlangflow-baselangflowDetection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for langflow, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update langflow to 1.5.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-8c4j-f57c-35cf is resolved across your whole dependency graph.
Workarounds
Put an independent control in front of the weakness: restrict the affected endpoint or interface to trusted networks, require an additional authentication factor or proxy-level check, and invalidate existing sessions and credentials in case the flaw has already been used.
Frequently Asked Questions
Is GHSA-8c4j-f57c-35cf in your dependencies?
Find it across PyPI, including transitive dependencies.