fix(security): enforce plugin and hook path containment

This commit is contained in:
Peter Steinberger
2026-02-19 15:34:58 +01:00
parent 10379e7dcd
commit 81b19aaa1a
14 changed files with 387 additions and 8 deletions

View File

@@ -5,6 +5,7 @@ import { createJiti } from "jiti";
import type { OpenClawConfig } from "../config/config.js";
import type { GatewayRequestHandler } from "../gateway/server-methods/types.js";
import { createSubsystemLogger } from "../logging/subsystem.js";
import { isPathInsideWithRealpath } from "../security/scan-paths.js";
import { resolveUserPath } from "../utils.js";
import { clearPluginCommands } from "./commands.js";
import {
@@ -485,6 +486,24 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
continue;
}
if (
!isPathInsideWithRealpath(candidate.rootDir, candidate.source, {
requireRealpath: true,
})
) {
record.status = "error";
record.error = "plugin entry path escapes plugin root";
registry.plugins.push(record);
seenIds.set(pluginId, candidate.origin);
registry.diagnostics.push({
level: "error",
pluginId: record.id,
source: record.source,
message: record.error,
});
continue;
}
let mod: OpenClawPluginModule | null = null;
try {
mod = getJiti()(candidate.source) as OpenClawPluginModule;