fix(security): scrub all secret fields on flow and project export (#14639)
* fix(security): scrub all secret fields on flow and project export
Export paths sanitized flow node templates with `remove_api_keys`, which
nulls a field only when it is both `password`-marked and named like an API
key (`has_api_terms`). A `password`-marked field under an ordinary name, or
a credential-bearing connection string, was therefore serialized verbatim
into the exported JSON/ZIP.
`strip_secret_field_values` already classifies these correctly — it is what
the public-flow endpoint uses — but the export paths were never migrated to
it. Move them over:
- `flows_helpers._build_flows_download_response` (POST /api/v1/flows/download/)
- `projects_files.download_project_flows` (GET /api/v1/projects/download/{id})
- `flow_version.strip_version_data` (version reads with strip_keys=True)
Adds `strip_flow_secrets` to `langflow.utils.flow_secrets` for the two call
sites that hold a flow envelope rather than a bare flow-data mapping. It
detaches `data` before scrubbing, so exporting no longer risks mutating the
ORM-backed payload, and it leaves an envelope without a `data` key untouched.
`remove_api_keys` is retained for the `LANGFLOW_REMOVE_API_KEYS` save-path
setting, whose persistence semantics are deliberately unchanged.
Regression coverage in test_export_secret_sanitization.py exercises all three
boundaries — the two download endpoints end to end plus the version-data
scrubber — asserting secret values are nulled, non-secret fields survive, and
no secret literal appears anywhere in the serialized payload.
Fixes LE-2240
* fix(security): detach an empty flow-data mapping on export
strip_flow_secrets documents that the returned envelope's data is detached so
the caller never mutates the ORM-backed payload it serialized from. A falsy but
present mapping short-circuited on 'not flow_data' and returned the caller's own
object, so an empty data dict was aliased rather than copied. Only None
short-circuits now. E
Eric Hare committed
fc3810da0cd3a6d8c0240f48ee26f00bd71906ed
Parent: 4dad2ad
Committed by GitHub <noreply@github.com>
on 8/19/2026, 5:36:40 PM