

























@@ -298,6 +298,61 @@ describe("installPluginFromNpmSpec", () => {
298298});
299299});
300300301+it("allows official catalog-matched npm plugins through the trusted scanner path", async () => {
302+const npmRoot = path.join(suiteTempRootTracker.makeTempDir(), "npm");
303+const warnings: string[] = [];
304+mockNpmViewAndInstall({
305+spec: "@openclaw/feishu@2026.5.2",
306+packageName: "@openclaw/feishu",
307+version: "2026.5.2",
308+pluginId: "feishu",
309+ npmRoot,
310+indexJs: `const token = process.env.FEISHU_BOT_TOKEN;\nfetch("https://open.feishu.cn/open-apis/bot/v2/hook", { headers: { authorization: token } });`,
311+});
312+313+const result = await installPluginFromNpmSpec({
314+spec: "@openclaw/feishu@2026.5.2",
315+expectedPluginId: "feishu",
316+npmDir: npmRoot,
317+logger: {
318+info: () => {},
319+warn: (msg: string) => warnings.push(msg),
320+},
321+});
322+323+expect(result.ok).toBe(true);
324+expect(
325+warnings.some((warning) =>
326+warning.includes("allowed because it is an official OpenClaw package"),
327+),
328+).toBe(true);
329+});
330+331+it("keeps blocking dangerous npm installs that do not match the official catalog", async () => {
332+const npmRoot = path.join(suiteTempRootTracker.makeTempDir(), "npm");
333+mockNpmViewAndInstall({
334+spec: "@openclaw/feishu-spoof@2026.5.2",
335+packageName: "@openclaw/feishu-spoof",
336+version: "2026.5.2",
337+pluginId: "feishu",
338+ npmRoot,
339+indexJs: `const token = process.env.FEISHU_BOT_TOKEN;\nfetch("https://open.feishu.cn/open-apis/bot/v2/hook", { headers: { authorization: token } });`,
340+});
341+342+const result = await installPluginFromNpmSpec({
343+spec: "@openclaw/feishu-spoof@2026.5.2",
344+expectedPluginId: "feishu",
345+npmDir: npmRoot,
346+logger: { info: () => {}, warn: () => {} },
347+});
348+349+expect(result.ok).toBe(false);
350+if (!result.ok) {
351+expect(result.code).toBe(PLUGIN_INSTALL_ERROR_CODE.SECURITY_SCAN_BLOCKED);
352+expect(result.error).toContain("dangerous code patterns detected");
353+}
354+});
355+301356it("rejects non-registry npm specs", async () => {
302357const result = await installPluginFromNpmSpec({ spec: "github:evil/evil" });
303358expect(result.ok).toBe(false);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。