{"id":"CVE-2026-34046","aliases":["GHSA-8c4j-f57c-35cf","PYSEC-2026-2567","PYSEC-2026-2570"],"url":"https://o3.security/vulnerability/CVE-2026-34046","summary":"Langflow: Authenticated Users Can Read, Modify, and Delete Any Flow via Missing Ownership Check","details":"## Vulnerability\n\n### IDOR in `GET/PATCH/DELETE /api/v1/flow/{flow_id}`\n\nThe `_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.\n\nThis exposed any authenticated user to:\n\n- **Read** any other user's flow, including embedded plaintext API keys\n- **Modify** the logic of another user's AI agents\n- **Delete** flows belonging to other users\n\nThe 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.\n\n---\n\n## Fix (PR #8956)\n\nThe fix removes the `AUTO_LOGIN` conditional entirely and unconditionally scopes the query to the requesting user:\n\n```diff\n-    auth_settings = settings_service.auth_settings\n-    stmt = select(Flow).where(Flow.id == flow_id)\n-    if auth_settings.AUTO_LOGIN:\n-        stmt = stmt.where(\n-            (Flow.user_id == user_id) | (Flow.user_id == None)  # noqa: E711\n-        )\n+    stmt = select(Flow).where(Flow.id == flow_id).where(Flow.user_id == user_id)\n```\n\nAll 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.\n\n---\n\n## Acknowledgements\n\nLangflow thanks the security researcher who responsibly disclosed this vulnerability:\n\n- **[@chximn-dt](https://github.com/chximn-dt)**","published":"2026-03-27T20:06:35.836Z","modified":"2026-08-12T03:51:37.474113832Z","cvss":null,"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"PyPI","name":"langflow","fixedVersion":"1.5.1"},{"ecosystem":"PyPI","name":"langflow-base","fixedVersion":"0.5.1"}],"fix":{"url":"https://github.com/langflow-ai/langflow/pull/8956","label":"langflow-ai/langflow#8956"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/34xxx/CVE-2026-34046.json"},{"type":"ADVISORY","url":"https://github.com/langflow-ai/langflow/security/advisories/GHSA-8c4j-f57c-35cf"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34046"},{"type":"FIX","url":"https://github.com/langflow-ai/langflow/pull/8956"},{"type":"PACKAGE","url":"https://github.com/langflow-ai/langflow"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:37.474113832Z"}}