# Risk map — langflow-ai/langflow

> Canonical page: https://codevetter.com/unpack/langflow/risk-map

# Risk map — langflow-ai/langflow

Scanned commit 5621dcfd84e11108e4cc1ecb0c51f41053c4211c (2026-09-15). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The dominant risk theme is executing caller-influenced code: custom components are arbitrary Python exec'd at build/validation time, stored flow JSON embeds component source, and multiple policy layers (custom_component_admin_only, tweak policy, owner-only tweaks, catalog/model-provider policy) exist to contain that. Auth surface risk is managed but default-lenient (AUTO_LOGIN, permissive CORS with warnings, SSRF protection off by default, short SECRET_KEY tolerated with legacy decryption). Supply-chain and infra footguns include remote bundle zips at startup, entry-point service replacement, per-worker in-memory job queues, and pickle in the cache service.
- Custom components execute arbitrary Python: lfx/custom/validate.py calls exec() on component code in several places (function extraction, class validation), explicitly noqa'd S102; code execution tools (python_repl) run user code gated by ensure_code_execution_enabled() + LANGFLOW_ALLOW_CUSTOM_COMPONENTS / LANGFLOW_BLOCK_CODE_INTERPRETER_COMPONENTS. — [src/lfx/src/lfx/custom/validate.py#L95-188](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/custom/validate.py#L95-L188) [src/lfx/src/lfx/components/tools/python_repl.py#L90-118](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/components/tools/python_repl.py#L90-L118) [src/lfx/src/lfx/utils/python_repl_security.py#L190-255](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/utils/python_repl_security.py#L190-L255)
- Stored flows carry component source: a regular user can persist component code via the flow-write API then execute it — mitigated by prepare_flow_build_for_user applying custom_component_admin_only policy to stored bytes on a detached copy before Graph.from_payload in both /run and /build paths. — [src/backend/base/langflow/api/v1/endpoints.py#L410-431](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/api/v1/endpoints.py#L410-L431) [src/backend/base/langflow/api/v1/chat.py#L417-434](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/api/v1/chat.py#L417-L434)
- An opt-in QEMU microVM sandbox backend (LANGFLOW_SANDBOX_BACKEND=exec-sandbox, extra `langflow-base[sandbox]`) exists for code-execution components; plugin backends are gated by LANGFLOW_SANDBOX_BACKEND_PLUGINS; shutdown_sandbox is called in lifespan cleanup so recycled workers don't leak VMs. — [src/lfx/src/lfx/utils/sandbox/exec_sandbox.py](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/utils/sandbox/exec_sandbox.py) [src/lfx/src/lfx/utils/sandbox/registry.py#L90-261](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/utils/sandbox/registry.py#L90-L261) [src/backend/base/langflow/main.py#L813-824](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/main.py#L813-L824) [pyproject.toml#L202-208](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/pyproject.toml#L202-L208)
- SSRF protection is OFF by default (LANGFLOW_SSRF_PROTECTION_ENABLED unset/false 'for backward compatibility'); when enabled it blocks private IP/localhost/metadata endpoints with an allowlist LANGFLOW_SSRF_ALLOWED_HOSTS — a meaningful default-off posture for a tool that fetches URLs. — [.env.example#L171-183](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/.env.example#L171-L183)
- CORS defaults are permissive: wildcard origin + credentials historically enabled credentialed cross-site requests; code now force-disables credentials when '*' is present and warns that stricter defaults arrive in v2.0 — operators on current versions still get all-origins by default. — [src/backend/base/langflow/main.py#L167-189](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/main.py#L167-L189) [src/backend/base/langflow/main.py#L879-906](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/main.py#L879-L906)
- AUTO_LOGIN creates a superuser with a generated random password (legacy default password is ignored/rotated) guarded by a FileLock; teardown deletes the unused default superuser when AUTO_LOGIN is off — the warning text notes auto-login mode should not be exposed since access implies code execution. — [src/backend/base/langflow/services/utils.py#L141-263](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/services/utils.py#L141-L263) [src/backend/base/langflow/services/auth/utils.py](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/services/auth/utils.py) [src/lfx/src/lfx/utils/python_repl_security.py#L32](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/utils/python_repl_security.py#L32)
- SECRET_KEY handling: short secrets derive the Fernet key via SHA-256 for new encryption, but a MultiFernet retains a deterministic random.Random(seed)-derived legacy key for decryption — deployments with weak SECRET_KEYs keep weak key derivation, only warned about (MINIMUM_SECRET_KEY_LENGTH=32 warning). — [src/backend/base/langflow/services/auth/utils.py#L416-469](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/services/auth/utils.py#L416-L469) [src/lfx/src/lfx/services/settings/auth.py#L32-51](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/services/settings/auth.py#L32-L51)
- Remote bundle URLs (settings.bundle_urls) download zip archives (incl. GitHub repos) at startup and extract component files into temp dirs that are added to components_path — remote code is fetched and executed; errors are logged but never block startup. — [src/backend/base/langflow/initial_setup/setup.py#L1072-1146](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/initial_setup/setup.py#L1072-L1146) [src/backend/base/langflow/main.py#L159-164](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/main.py#L159-L164)
- Entry-point plugin loading replaces service classes: any installed distribution can register `lfx.services` entry points; subclass validation exists only for AUTHORIZATION/CATALOG_POLICY/MODEL_PROVIDER_POLICY/POLICY_BUNDLE services, and lfx.toml config paths get override=True — a malicious/misconfigured package can swap less-guarded services. — [src/lfx/src/lfx/services/manager.py#L407-476](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/services/manager.py#L407-L476) [src/lfx/src/lfx/services/manager.py#L488-558](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/lfx/src/lfx/services/manager.py#L488-L558)
- Multi-worker state hazards are extensive: in-memory job queues break POLLING/STREAMING event delivery (~half of GET /build/<job_id>/events land on the wrong worker), MCP-over-SSE is broken, rate limits multiply per worker, orphan sweep is node-local — the guard refuses boot but the bypass env var exists. — [src/backend/base/langflow/__main__.py#L248-348](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/__main__.py#L248-L348)
- Pickle is used intentionally in the cache service (ruff S301 waived for services/cache/*) — safe for local memory/SQLite but a deserialization risk if pointed at an untrusted/shared backend. — [pyproject.toml#L432-434](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/pyproject.toml#L432-L434) [src/backend/base/langflow/services/cache/service.py](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/services/cache/service.py)
- worker.py is vestigial Celery code: test_celery/build_vertex tasks exist but process_graph_cached_task raises NotImplementedError('This task is not implemented yet') — dead execution path kept in the tree. — [src/backend/base/langflow/worker.py](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/worker.py)
- main.py is a 1277-line hotspot concentrating env-gated startup ordering; several comments document past races (UnboundLocalError on temp_dirs masking early failures, issue #13634; preload gating via is_step_complete to skip work in forked workers) — edit with care, ordering is load-bearing. (inferred) — [src/backend/base/langflow/main.py#L214-227](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/main.py#L214-L227) [src/backend/base/langflow/main.py#L322-428](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/main.py#L322-L428)
- MCP session manager spawns subprocesses for stdio servers; cleanup_mcp_sessions is deliberately first in the finally block so interrupted shutdowns still kill them; idle sessions are reaped by interval/timeout tunables clamped to prevent CPU spin. — [src/backend/base/langflow/main.py#L694-697](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/src/backend/base/langflow/main.py#L694-L697) [.env.example#L190-204](https://github.com/langflow-ai/langflow/blob/5621dcfd84e11108e4cc1ecb0c51f41053c4211c/.env.example#L190-L204)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
