CVE-2025-68478 — langflow
HIGHCVE-2025-68478 is a high-severity (CVSS 7.1) CWE-73 vulnerability in langflow. A fix is available for langflow — see the affected versions and patch details below.
Langflow Vulnerable to External Control of File Name or Path
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
Exploitation and automatability from CISA’s SSVC triage for CVE-2025-68478.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
CVE-2025-68478 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 378,156 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
langflowReal-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 Overview
If an arbitrary path is specified in the request body's fs_path, the server serializes the Flow object into JSON and creates/overwrites a file at that path. There is no path restriction, normalization, or allowed directory enforcement, so absolute paths (e.g., /etc/poc.txt) are interpreted as is.
Vulnerable Code
-
It receives the request body (flow), updates the DB, and then passes it to the file-writing sink.
@router.post("/", response_model=FlowRead, status_code=201) async def create_flow( *, session: DbSession, flow: FlowCreate, current_user: CurrentActiveUser, ): try: db_flow = await _new_flow(session=session, flow=flow, user_id=current_user.id) await session.commit() await session.refresh(db_flow) await _save_flow_to_fs(db_flow) except Exception as e: -
Applies authentication dependency (requires API Key/JWT) when accessing the endpoint.
CurrentActiveUser = Annotated[User, Depends(get_current_active_user)] CurrentActiveMCPUser = Annotated[User, Depends(get_current_active_user_mcp)] DbSession = Annotated[AsyncSession, Depends(get_session)] -
The client can directly specify the save path, including
fs_path.): try: await _verify_fs_path(flow.fs_path) """Create a new flow.""" -
It attempts to create the file (or the file, in the case of a path without a parent) directly without path validation.
async def _verify_fs_path(path: str | None) -> None: if path: path_ = Path(path) if not await path_.exists(): await path_.touch() -
Serializes the Flow object to JSON and writes it to the specified path in "w" mode (overwriting).
async def _save_flow_to_fs(flow: Flow) -> None: if flow.fs_path: async with async_open(flow.fs_path, "w") as f: try: await f.write(flow.model_dump_json()) except OSError: await logger.aexception("Failed to write flow %s to path %s", flow.name, flow.fs_path)
PoC Description
When an authenticated user passes an arbitrary path in fs_path, the Flow JSON is written to that path. Since /tmp is usually writable, it is easy to reproduce. In a production environment, writing to system-protected directories may fail depending on permissions.
PoC
-
Before Exploit
<img width="1918" height="658" alt="image" src="https://github.com/user-attachments/assets/fe3c2306-091d-4cb0-b4dc-c7fb63c03d8d" /> -
After Exploit
<img width="1918" height="742" alt="image" src="https://github.com/user-attachments/assets/cc0b0c96-1c2d-4d56-b558-5ba97e0ec174" />curl -sS -X POST "http://localhost:7860/api/v1/flows/" \ -H "Content-Type: application/json" \ -H "x-api-key: sk-8Kyzf9IQ-UEJ_OtSTaJq4eniMT9_JKgZ7__q8PNkoxc" \ -d '{"name":"poc-etc","data":{"nodes":[],"edges":[]},"fs_path":"/tmp/POC.txt"}'
Impact
- Authenticated Arbitrary File Write (within server permission scope): Risk of corrupting configuration/log/task files, disrupting application behavior, and tampering with files read by other components.
- Both absolute and relative paths are allowed, enabling base directory traversal. The risk of overwriting system files increases in environments with root privileges or weak mount/permission settings.
- The file content is limited to Flow JSON, but the impact is severe if the target file is parsed by a JSON parser or is subject to subsequent processing.
- In production environments, it is essential to enforce a save root, normalize paths, block symlink traversal, and minimize permissions.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | langflow | all versions | 1.7.1pip install --upgrade 'langflow==1.7.1' |
Detection & 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.7.1 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2025-68478 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2025-68478 can be triaged on real exposure rather than presence alone.
Tailored to CVE-2025-68478. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is CVE-2025-68478 in your dependencies?
O3 Security finds CVE-2025-68478 across PyPI dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.