mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-01 20:30:22 +00:00
fix(security): harden npm plugin and hook install integrity flow
This commit is contained in:
@@ -29,6 +29,16 @@ export type PluginUpdateSummary = {
|
||||
outcomes: PluginUpdateOutcome[];
|
||||
};
|
||||
|
||||
export type PluginUpdateIntegrityDriftParams = {
|
||||
pluginId: string;
|
||||
spec: string;
|
||||
expectedIntegrity: string;
|
||||
actualIntegrity: string;
|
||||
resolvedSpec?: string;
|
||||
resolvedVersion?: string;
|
||||
dryRun: boolean;
|
||||
};
|
||||
|
||||
export type PluginChannelSyncSummary = {
|
||||
switchedToBundled: string[];
|
||||
switchedToNpm: string[];
|
||||
@@ -143,6 +153,7 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
pluginIds?: string[];
|
||||
skipIds?: Set<string>;
|
||||
dryRun?: boolean;
|
||||
onIntegrityDrift?: (params: PluginUpdateIntegrityDriftParams) => boolean | Promise<boolean>;
|
||||
}): Promise<PluginUpdateSummary> {
|
||||
const logger = params.logger ?? {};
|
||||
const installs = params.config.plugins?.installs ?? {};
|
||||
@@ -210,6 +221,25 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
mode: "update",
|
||||
dryRun: true,
|
||||
expectedPluginId: pluginId,
|
||||
expectedIntegrity: record.integrity,
|
||||
onIntegrityDrift: async (drift) => {
|
||||
const payload: PluginUpdateIntegrityDriftParams = {
|
||||
pluginId,
|
||||
spec: drift.spec,
|
||||
expectedIntegrity: drift.expectedIntegrity,
|
||||
actualIntegrity: drift.actualIntegrity,
|
||||
resolvedSpec: drift.resolution.resolvedSpec,
|
||||
resolvedVersion: drift.resolution.version,
|
||||
dryRun: true,
|
||||
};
|
||||
if (params.onIntegrityDrift) {
|
||||
return await params.onIntegrityDrift(payload);
|
||||
}
|
||||
logger.warn?.(
|
||||
`Integrity drift for "${pluginId}" (${payload.resolvedSpec ?? payload.spec}): expected ${payload.expectedIntegrity}, got ${payload.actualIntegrity}`,
|
||||
);
|
||||
return true;
|
||||
},
|
||||
logger,
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -257,6 +287,25 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
spec: record.spec,
|
||||
mode: "update",
|
||||
expectedPluginId: pluginId,
|
||||
expectedIntegrity: record.integrity,
|
||||
onIntegrityDrift: async (drift) => {
|
||||
const payload: PluginUpdateIntegrityDriftParams = {
|
||||
pluginId,
|
||||
spec: drift.spec,
|
||||
expectedIntegrity: drift.expectedIntegrity,
|
||||
actualIntegrity: drift.actualIntegrity,
|
||||
resolvedSpec: drift.resolution.resolvedSpec,
|
||||
resolvedVersion: drift.resolution.version,
|
||||
dryRun: false,
|
||||
};
|
||||
if (params.onIntegrityDrift) {
|
||||
return await params.onIntegrityDrift(payload);
|
||||
}
|
||||
logger.warn?.(
|
||||
`Integrity drift for "${pluginId}" (${payload.resolvedSpec ?? payload.spec}): expected ${payload.expectedIntegrity}, got ${payload.actualIntegrity}`,
|
||||
);
|
||||
return true;
|
||||
},
|
||||
logger,
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -283,6 +332,12 @@ export async function updateNpmInstalledPlugins(params: {
|
||||
spec: record.spec,
|
||||
installPath: result.targetDir,
|
||||
version: nextVersion,
|
||||
resolvedName: result.npmResolution?.name,
|
||||
resolvedVersion: result.npmResolution?.version,
|
||||
resolvedSpec: result.npmResolution?.resolvedSpec,
|
||||
integrity: result.npmResolution?.integrity,
|
||||
shasum: result.npmResolution?.shasum,
|
||||
resolvedAt: result.npmResolution?.resolvedAt,
|
||||
});
|
||||
changed = true;
|
||||
|
||||
@@ -406,6 +461,12 @@ export async function syncPluginsForUpdateChannel(params: {
|
||||
spec,
|
||||
installPath: result.targetDir,
|
||||
version: result.version,
|
||||
resolvedName: result.npmResolution?.name,
|
||||
resolvedVersion: result.npmResolution?.version,
|
||||
resolvedSpec: result.npmResolution?.resolvedSpec,
|
||||
integrity: result.npmResolution?.integrity,
|
||||
shasum: result.npmResolution?.shasum,
|
||||
resolvedAt: result.npmResolution?.resolvedAt,
|
||||
sourcePath: undefined,
|
||||
});
|
||||
summary.switchedToNpm.push(pluginId);
|
||||
|
||||
Reference in New Issue
Block a user