fix: close marketplace client review findings

This commit is contained in:
2026-08-28 21:01:51 +08:00
parent 8dfa542860
commit 1614f7efc1
25 changed files with 1224 additions and 143 deletions

View File

@@ -23,7 +23,7 @@ import {
packagedResourcesDirectory,
} from '../probe-pi-packaged-runtime.mjs';
const { listPackage } = createRequire(import.meta.url)('@electron/asar');
const { extractFile, listPackage } = createRequire(import.meta.url)('@electron/asar');
const PRODUCT_NAME = 'Makelore';
const LINUX_EXECUTABLE_NAME = 'niancode';
@@ -56,6 +56,7 @@ const MARKETPLACE_ARTIFACT_MARKERS = Object.freeze({
'我的插件',
]),
});
const CODE_OWNED_PLUGIN_SIGNING_KEYS_SOURCE_MARKER = 'makelore.plugin-trust.code-owned.v1';
const PI_AI_PROVIDER_PREFIX = 'pi-runtime/node_modules/@earendil-works/pi-ai/dist/providers/';
const PI_AI_PROVIDER_ASAR_PREFIX = 'app.asar/node_modules/@earendil-works/pi-ai/dist/providers/';
export const BUNDLED_CODING_PLUGIN_RESOURCE_ROOT = 'resources/coding-plugins';
@@ -296,7 +297,9 @@ export function verifyMarketplaceClientArtifact(appAsarContents, productionTrust
if (missing.length > 0) {
throw new Error(`Packaged app.asar does not contain Marketplace contract markers: ${missing.join(', ')}`);
}
if (!/CODE_OWNED_PLUGIN_SIGNING_KEYS\s*=\s*Object\.freeze\(\s*\{\}\s+as/u.test(productionTrustSource)
const hasEmptyCodeOwnedTrust = /(?:CODE_OWNED_PLUGIN_SIGNING_KEYS\s*=\s*)?Object\.freeze\(\s*\{\}\s*(?:as\s+[^)]*)?\)/u.test(productionTrustSource);
if (!hasEmptyCodeOwnedTrust
|| !productionTrustSource.includes(CODE_OWNED_PLUGIN_SIGNING_KEYS_SOURCE_MARKER)
|| productionTrustSource.includes('process.env')
|| productionTrustSource.includes('-----BEGIN PRIVATE KEY-----')
|| productionTrustSource.includes('-----BEGIN ED25519 PRIVATE KEY-----')) {
@@ -314,6 +317,36 @@ export function verifyMarketplaceClientArtifact(appAsarContents, productionTrust
};
}
/**
* Read the Marketplace trust source from the packaged application itself.
* Checkout sources are not evidence of what an installed app will trust.
*/
export async function readPackagedMarketplaceTrustSource(appAsar) {
const candidates = listPackage(appAsar, { isPack: false })
.filter((entry) => /\.(?:js|mjs|cjs)$/u.test(entry));
for (const entry of candidates) {
const filename = entry.replace(/^[/\\]+/u, '');
let source;
try {
source = extractFile(appAsar, filename).toString('utf8');
} catch {
continue;
}
const trustAssignment = source.match(
/CODE_OWNED_PLUGIN_SIGNING_KEYS\s*=\s*Object\.freeze\(\s*\{\}\s*(?:as\s+[^)]*)?\)/u,
);
if (trustAssignment) return trustAssignment[0];
const compiledTrust = source.match(
/(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*=\s*Object\.freeze\(\s*\{\}\s*\)\s*;(?=[\s\S]{0,512}?sourceMarker\s*:\s*["']makelore\.plugin-trust\.code-owned\.v1["'])/u,
);
if (compiledTrust) {
return `${compiledTrust[0]} sourceMarker: ${CODE_OWNED_PLUGIN_SIGNING_KEYS_SOURCE_MARKER}`;
}
}
throw new Error('Packaged app.asar does not contain the Marketplace trust source');
}
async function filesContainingNeedles(root, needles) {
const matches = [];
const visit = async (path) => {
@@ -564,10 +597,7 @@ export async function verifyPiProductArtifact({ projectRoot, executable }) {
throw new Error(`Pi runtime manifest contains absolute paths: ${JSON.stringify(absoluteManifestValues)}`);
}
const appAsarContents = await readFile(appAsar);
const marketplaceTrustSource = await readFile(
join(root, 'electron', 'coding-plugins', 'trusted-keys.ts'),
'utf8',
);
const marketplaceTrustSource = await readPackagedMarketplaceTrustSource(appAsar);
const physicalOpenCodePaths = await collectForbiddenResourcePaths(resourcesDirectory);
const asarOpenCodePaths = collectForbiddenAsarPaths(appAsar);
const openCodeResourcePaths = classifyOpenCodeResourcePaths([