Files
openclaw/src/plugins/install-security-scan.ts
Pavan Kumar Gondhi 39bcd1e088 fix(plugins): scan installed dependency runtime code [AI] (#81066)
* fix: scan installed plugin dependency code

* addressing review-skill

* addressing review-skill

* addressing codex review

* addressing codex review

* addressing codex review

* addressing codex review

* addressing codex review

* addressing codex review

* addressing codex review

* addressing codex review

* addressing ci

* addressing ci

* docs: add changelog entry for PR merge
2026-05-13 10:26:24 +05:30

121 lines
3.6 KiB
TypeScript

type InstallScanLogger = {
warn?: (message: string) => void;
};
export type { InstallSafetyOverrides } from "./install-security-scan.types.js";
import type { InstallSafetyOverrides } from "./install-security-scan.types.js";
export type InstallSecurityScanResult = {
blocked?: {
code?: "security_scan_blocked" | "security_scan_failed";
reason: string;
};
};
export type PluginInstallRequestKind =
| "plugin-dir"
| "plugin-archive"
| "plugin-file"
| "plugin-npm"
| "plugin-git";
export type SkillInstallSpecMetadata = {
id?: string;
kind: "brew" | "node" | "go" | "uv" | "download";
label?: string;
bins?: string[];
os?: string[];
formula?: string;
package?: string;
module?: string;
url?: string;
archive?: string;
extract?: boolean;
stripComponents?: number;
targetDir?: string;
};
export type PackageExecutableScanMetadata = {
runtimeExtensions?: readonly string[];
runtimeSetupEntry?: string;
setupEntry?: string;
};
async function loadInstallSecurityScanRuntime() {
return await import("./install-security-scan.runtime.js");
}
export async function scanBundleInstallSource(
params: InstallSafetyOverrides & {
logger: InstallScanLogger;
pluginId: string;
sourceDir: string;
requestKind?: PluginInstallRequestKind;
requestedSpecifier?: string;
mode?: "install" | "update";
version?: string;
},
): Promise<InstallSecurityScanResult | undefined> {
const { scanBundleInstallSourceRuntime } = await loadInstallSecurityScanRuntime();
return await scanBundleInstallSourceRuntime(params);
}
export async function scanPackageInstallSource(
params: InstallSafetyOverrides & {
extensions: string[];
logger: InstallScanLogger;
packageDir: string;
packageMetadata?: PackageExecutableScanMetadata;
pluginId: string;
requestKind?: PluginInstallRequestKind;
requestedSpecifier?: string;
mode?: "install" | "update";
packageName?: string;
manifestId?: string;
version?: string;
},
): Promise<InstallSecurityScanResult | undefined> {
const { scanPackageInstallSourceRuntime } = await loadInstallSecurityScanRuntime();
return await scanPackageInstallSourceRuntime(params);
}
export async function scanInstalledPackageDependencyTree(params: {
additionalPackageDirs?: string[];
allowManagedNpmRootPackagePeerSymlinks?: boolean;
dangerouslyForceUnsafeInstall?: boolean;
dependencyScanRootDir?: string;
logger: InstallScanLogger;
packageDir: string;
pluginId: string;
trustedSourceLinkedOfficialInstall?: boolean;
}): Promise<InstallSecurityScanResult | undefined> {
const { scanInstalledPackageDependencyTreeRuntime } = await loadInstallSecurityScanRuntime();
return await scanInstalledPackageDependencyTreeRuntime(params);
}
export async function scanFileInstallSource(
params: InstallSafetyOverrides & {
filePath: string;
logger: InstallScanLogger;
mode?: "install" | "update";
pluginId: string;
requestedSpecifier?: string;
},
): Promise<InstallSecurityScanResult | undefined> {
const { scanFileInstallSourceRuntime } = await loadInstallSecurityScanRuntime();
return await scanFileInstallSourceRuntime(params);
}
export async function scanSkillInstallSource(params: {
dangerouslyForceUnsafeInstall?: boolean;
installId: string;
installSpec?: SkillInstallSpecMetadata;
logger: InstallScanLogger;
origin: string;
skillName: string;
sourceDir: string;
}): Promise<InstallSecurityScanResult | undefined> {
const { scanSkillInstallSourceRuntime } = await loadInstallSecurityScanRuntime();
return await scanSkillInstallSourceRuntime(params);
}