refactor(security): share installed plugin directory scan helper

This commit is contained in:
Peter Steinberger
2026-02-19 00:29:07 +00:00
parent 6ae7e6fd1f
commit d6768098a1

View File

@@ -96,6 +96,26 @@ function formatCodeSafetyDetails(findings: SkillScanFinding[], rootDir: string):
.join("\n");
}
async function listInstalledPluginDirs(params: {
stateDir: string;
onReadError?: (error: unknown) => void;
}): Promise<{ extensionsDir: string; pluginDirs: string[] }> {
const extensionsDir = path.join(params.stateDir, "extensions");
const st = await safeStat(extensionsDir);
if (!st.ok || !st.isDir) {
return { extensionsDir, pluginDirs: [] };
}
const entries = await fs.readdir(extensionsDir, { withFileTypes: true }).catch((err) => {
params.onReadError?.(err);
return [];
});
const pluginDirs = entries
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)
.filter(Boolean);
return { extensionsDir, pluginDirs };
}
function resolveToolPolicies(params: {
cfg: OpenClawConfig;
agentTools?: AgentToolsConfig;
@@ -204,17 +224,9 @@ export async function collectPluginsTrustFindings(params: {
stateDir: string;
}): Promise<SecurityAuditFinding[]> {
const findings: SecurityAuditFinding[] = [];
const extensionsDir = path.join(params.stateDir, "extensions");
const st = await safeStat(extensionsDir);
if (!st.ok || !st.isDir) {
return findings;
}
const entries = await fs.readdir(extensionsDir, { withFileTypes: true }).catch(() => []);
const pluginDirs = entries
.filter((e) => e.isDirectory())
.map((e) => e.name)
.filter(Boolean);
const { extensionsDir, pluginDirs } = await listInstalledPluginDirs({
stateDir: params.stateDir,
});
if (pluginDirs.length === 0) {
return findings;
}
@@ -619,24 +631,19 @@ export async function collectPluginsCodeSafetyFindings(params: {
stateDir: string;
}): Promise<SecurityAuditFinding[]> {
const findings: SecurityAuditFinding[] = [];
const extensionsDir = path.join(params.stateDir, "extensions");
const st = await safeStat(extensionsDir);
if (!st.ok || !st.isDir) {
return findings;
}
const entries = await fs.readdir(extensionsDir, { withFileTypes: true }).catch((err) => {
findings.push({
checkId: "plugins.code_safety.scan_failed",
severity: "warn",
title: "Plugin extensions directory scan failed",
detail: `Static code scan could not list extensions directory: ${String(err)}`,
remediation:
"Check file permissions and plugin layout, then rerun `openclaw security audit --deep`.",
});
return [];
const { extensionsDir, pluginDirs } = await listInstalledPluginDirs({
stateDir: params.stateDir,
onReadError: (err) => {
findings.push({
checkId: "plugins.code_safety.scan_failed",
severity: "warn",
title: "Plugin extensions directory scan failed",
detail: `Static code scan could not list extensions directory: ${String(err)}`,
remediation:
"Check file permissions and plugin layout, then rerun `openclaw security audit --deep`.",
});
},
});
const pluginDirs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
for (const pluginName of pluginDirs) {
const pluginPath = path.join(extensionsDir, pluginName);