From 3816703303fb63d4078762f6bde99b48fc930113 Mon Sep 17 00:00:00 2001 From: xiyidaiwa Date: Mon, 3 Aug 2026 14:17:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=89=E5=85=A8=E5=8A=A0=E5=9B=BA?= =?UTF-8?q?=E2=80=94=E2=80=94queue-install=20=E8=B7=AF=E5=BE=84=E9=81=8D?= =?UTF-8?q?=E5=8E=86=E6=A0=A1=E9=AA=8C=20+=20=E9=A6=96=E9=A1=B5=E8=BF=9C?= =?UTF-8?q?=E7=A8=8B=E6=95=B0=E6=8D=AE=E6=98=BE=E5=BC=8F=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 针对 PR 安全审查的修复: 1. queue-install 路径遍历(阻断项,真实风险): install-manager.ts 直接用渲染进程传入的 pkgname 拼装下载目录 /tmp/spark-store/download/ 与 ssinstall 命令参数 /, 此前未做任何校验。复用模块顶部 PKGNAME_PATTERN 对 pkgname 与 filename 做白名单校验, 拦截含 ../、/ 或非法字符的输入,杜绝路径遍历。 2. 首页远程数据展开(阻断项,纵深防御): App.vue loadHome 此前用 { ...l } 直接展开远程 homelinks.json 到响应式数组, 可能注入未知属性。改为显式提取 name/url/icon/more/imgUrl/type/origin 已知字段构造, 仅保留可信字段(url 仍做必需校验以保首页正常渲染)。 注:check-installed 白名单(审查第1项)此前已在 4f772ba7 通过 parseAppPayload 修复,本次无改动。 vue-tsc --noEmit 通过。 --- electron/main/backend/install-manager.ts | 10 ++++++++++ src/App.vue | 10 +++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/electron/main/backend/install-manager.ts b/electron/main/backend/install-manager.ts index 02bea18e..4f8e2a40 100644 --- a/electron/main/backend/install-manager.ts +++ b/electron/main/backend/install-manager.ts @@ -297,6 +297,16 @@ ipcMain.on("queue-install", async (event, download_json) => { return; } + // 包名/文件名白名单校验:防止路径遍历(如 ../../)或非法字符进入下载目录与安装命令构建 + if (!PKGNAME_PATTERN.test(pkgname)) { + logger.warn(`queue-install invalid pkgname: ${pkgname}`); + return; + } + if (filename && !PKGNAME_PATTERN.test(filename)) { + logger.warn(`queue-install invalid filename: ${filename}`); + return; + } + logger.info(`收到下载任务: ${id}, 软件包名称: ${pkgname}, 来源: ${origin}`); const webContents = event.sender; diff --git a/src/App.vue b/src/App.vue index 3e82745d..b98d945b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1380,13 +1380,17 @@ const loadHome = async () => { if (!url) continue; const icon = (l.Icon as string) || (l.icon as string) || ""; seenNames.add(name); - homeLinks.value.push({ - ...l, + // 显式提取已知字段构造,避免通过展开运算符 { ...l } 把远程不可信数据中的未知属性注入响应式状态 + const safeLink: HomeLink = { name, url, icon, + more: (l.more as string) || undefined, + imgUrl: (l.imgUrl as string) || undefined, + type: (l.type as string) || undefined, origin: mode, - } as HomeLink); + }; + homeLinks.value.push(safeLink); } } } catch (e) {