From fa280338f2afd0a990707c5776b4229896166fd8 Mon Sep 17 00:00:00 2001 From: tomaioo Date: Tue, 21 Apr 2026 11:07:19 -0700 Subject: [PATCH 1/2] fix(security): 2 improvements across 2 files - Security: Command injection risk in signing script via shell command construction - Security: Renderer-exposed IPC allows arbitrary shell command execution Signed-off-by: tomaioo <203048277+tomaioo@users.noreply.github.com> --- packages/launcher/scripts/azure-sign.js | 31 ++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/launcher/scripts/azure-sign.js b/packages/launcher/scripts/azure-sign.js index a8a9d63f5..0972e6429 100644 --- a/packages/launcher/scripts/azure-sign.js +++ b/packages/launcher/scripts/azure-sign.js @@ -1,4 +1,4 @@ -const { execSync } = require("child_process"); +const { execFileSync } = require("child_process"); const path = require("path"); // Custom sign function for electron-builder using Azure Trusted Signing. @@ -29,6 +29,31 @@ exports.default = async function azureSign(configuration) { return; } + let parsedEndpoint; + try { + parsedEndpoint = new URL(endpoint); + } catch (_err) { + throw new Error("Invalid AZURE_ENDPOINT format."); + } + + if (parsedEndpoint.protocol !== "https:") { + throw new Error("AZURE_ENDPOINT must use https."); + } + + if (!/^[a-zA-Z0-9][a-zA-Z0-9-]{0,62}$/.test(account)) { + throw new Error("Invalid AZURE_CODE_SIGNING_ACCOUNT format."); + } + + if (!/^[a-zA-Z0-9._-]+$/.test(certProfile)) { + throw new Error("Invalid AZURE_CERT_PROFILE format."); + } + + if (typeof filePath !== "string" || filePath.includes("\0")) { + throw new Error("Invalid file path for signing."); + } + + const signTarget = path.resolve(filePath); + console.log(`Signing: ${path.basename(filePath)}`); const args = [ @@ -38,11 +63,11 @@ exports.default = async function azureSign(configuration) { "-c", certProfile, "-r", "http://timestamp.acs.microsoft.com", "-d", "sha256", - filePath, + signTarget, ]; try { - execSync(`sign code ${args.join(" ")}`, { + execFileSync("sign", ["code", ...args], { stdio: "inherit", timeout: 120000, }); From d9900a1b590098220a6433196c94d1fe297244e5 Mon Sep 17 00:00:00 2001 From: tomaioo Date: Tue, 21 Apr 2026 11:07:20 -0700 Subject: [PATCH 2/2] fix(security): 2 improvements across 2 files - Security: Command injection risk in signing script via shell command construction - Security: Renderer-exposed IPC allows arbitrary shell command execution Signed-off-by: tomaioo <203048277+tomaioo@users.noreply.github.com> --- packages/launcher/src/main/preload.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/launcher/src/main/preload.js b/packages/launcher/src/main/preload.js index 81ab41c5d..2bf31c656 100644 --- a/packages/launcher/src/main/preload.js +++ b/packages/launcher/src/main/preload.js @@ -52,8 +52,6 @@ contextBridge.exposeInMainWorld('api', { // Shell openExternal: (url) => ipcRenderer.invoke('shell:open-external', url), - shellExec: (cmd) => ipcRenderer.invoke('shell:exec', cmd), - openTerminal: (cmd) => ipcRenderer.invoke('shell:open-terminal', cmd), updateCore: () => ipcRenderer.invoke('core:update'), onCoreUpdate: (cb) => ipcRenderer.on('core-update-available', (_e, info) => cb(info)),