


























@@ -2606,6 +2606,119 @@ describe("installPluginFromArchive", () => {
26062606expectWarningIncludes(warnings, "dangerous code pattern");
26072607});
260826082609+it("scans runtime extension entry files in hidden directories", async () => {
2610+const { pluginDir, extensionsDir } = setupPluginInstallDirs();
2611+fs.mkdirSync(path.join(pluginDir, ".hidden"), { recursive: true });
2612+2613+fs.writeFileSync(
2614+path.join(pluginDir, "package.json"),
2615+JSON.stringify({
2616+name: "hidden-runtime-entry-plugin",
2617+version: "1.0.0",
2618+openclaw: {
2619+extensions: ["index.js"],
2620+runtimeExtensions: [".hidden/runtime.cjs"],
2621+},
2622+}),
2623+);
2624+fs.writeFileSync(path.join(pluginDir, "index.js"), "module.exports = {};\n");
2625+fs.writeFileSync(
2626+path.join(pluginDir, ".hidden", "runtime.cjs"),
2627+`const { execFileSync } = require("child_process");\nexecFileSync(process.execPath, ["-e", ""]);`,
2628+);
2629+2630+const { result, warnings } = await installFromDirWithWarnings({ pluginDir, extensionsDir });
2631+2632+expect(result.ok).toBe(false);
2633+expectWarningIncludes(warnings, "hidden/node_modules path");
2634+expectWarningIncludes(warnings, "dangerous code pattern");
2635+});
2636+2637+it("scans setup entry files in hidden directories", async () => {
2638+const { pluginDir, extensionsDir } = setupPluginInstallDirs();
2639+fs.mkdirSync(path.join(pluginDir, ".hidden"), { recursive: true });
2640+2641+fs.writeFileSync(
2642+path.join(pluginDir, "package.json"),
2643+JSON.stringify({
2644+name: "hidden-setup-entry-plugin",
2645+version: "1.0.0",
2646+openclaw: {
2647+extensions: ["index.js"],
2648+setupEntry: ".hidden/setup.cjs",
2649+},
2650+}),
2651+);
2652+fs.writeFileSync(path.join(pluginDir, "index.js"), "module.exports = {};\n");
2653+fs.writeFileSync(
2654+path.join(pluginDir, ".hidden", "setup.cjs"),
2655+`const { execFileSync } = require("child_process");\nexecFileSync(process.execPath, ["-e", ""]);`,
2656+);
2657+2658+const { result, warnings } = await installFromDirWithWarnings({ pluginDir, extensionsDir });
2659+2660+expect(result.ok).toBe(false);
2661+expectWarningIncludes(warnings, "hidden/node_modules path");
2662+expectWarningIncludes(warnings, "dangerous code pattern");
2663+});
2664+2665+it("scans runtime setup entry files in hidden directories", async () => {
2666+const { pluginDir, extensionsDir } = setupPluginInstallDirs();
2667+fs.mkdirSync(path.join(pluginDir, ".hidden"), { recursive: true });
2668+2669+fs.writeFileSync(
2670+path.join(pluginDir, "package.json"),
2671+JSON.stringify({
2672+name: "hidden-runtime-setup-entry-plugin",
2673+version: "1.0.0",
2674+openclaw: {
2675+extensions: ["index.js"],
2676+setupEntry: "setup.ts",
2677+runtimeSetupEntry: ".hidden/setup.cjs",
2678+},
2679+}),
2680+);
2681+fs.writeFileSync(path.join(pluginDir, "index.js"), "module.exports = {};\n");
2682+fs.writeFileSync(path.join(pluginDir, "setup.ts"), "export {};\n");
2683+fs.writeFileSync(
2684+path.join(pluginDir, ".hidden", "setup.cjs"),
2685+`const { execFileSync } = require("child_process");\nexecFileSync(process.execPath, ["-e", ""]);`,
2686+);
2687+2688+const { result, warnings } = await installFromDirWithWarnings({ pluginDir, extensionsDir });
2689+2690+expect(result.ok).toBe(false);
2691+expectWarningIncludes(warnings, "hidden/node_modules path");
2692+expectWarningIncludes(warnings, "dangerous code pattern");
2693+});
2694+2695+it("scans inferred runtime entry files in hidden directories", async () => {
2696+const { pluginDir, extensionsDir } = setupPluginInstallDirs();
2697+fs.mkdirSync(path.join(pluginDir, ".hidden"), { recursive: true });
2698+2699+fs.writeFileSync(
2700+path.join(pluginDir, "package.json"),
2701+JSON.stringify({
2702+name: "hidden-inferred-runtime-entry-plugin",
2703+version: "1.0.0",
2704+openclaw: {
2705+extensions: [".hidden/index.ts"],
2706+},
2707+}),
2708+);
2709+fs.writeFileSync(path.join(pluginDir, ".hidden", "index.ts"), "export {};\n");
2710+fs.writeFileSync(
2711+path.join(pluginDir, ".hidden", "index.js"),
2712+`const { execFileSync } = require("child_process");\nexecFileSync(process.execPath, ["-e", ""]);`,
2713+);
2714+2715+const { result, warnings } = await installFromDirWithWarnings({ pluginDir, extensionsDir });
2716+2717+expect(result.ok).toBe(false);
2718+expectWarningIncludes(warnings, "hidden/node_modules path");
2719+expectWarningIncludes(warnings, "dangerous code pattern");
2720+});
2721+26092722it("blocks install when scanner throws", async () => {
26102723const scanSpy = vi
26112724.spyOn(installSecurityScan, "scanPackageInstallSource")
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。