T07 · Tool Hijacking and Spoofing
- Location
scripts/run.js:120- Finding
Unverified Local Package Resolution Enables Arbitrary Code Execution
- Content
View full analysis
Vulnerability Details
File Location:
scripts/run.js:120-139,scripts/run.js:164-180
Vulnerability Type: Untrusted local module resolution and missing dependency verification
Risk Level: HighVulnerable Code
js function resolveCliEntry() { const nodeBinDir = path.dirname(process.execPath); const candidateRoots = [ path.join(nodeBinDir, '..', 'lib', 'node_modules'), path.join(nodeBinDir, 'node_modules'), path.join(__dirname, '..', 'node_modules'), path.join(process.cwd(), 'node_modules'), ]; for (const root of candidateRoots) { const candidate = path.join(root, PINNED_PACKAGE, 'dist', 'cli.js'); try { if (fs.statSync(candidate).isFile()) return candidate; } catch (_) { /* not present at this root; continue */ } } try { return require.resolve(`${PINNED_PACKAGE}/dist/cli.js`, { paths: candidateRoots }); } catch (_) { return null; } }js const cliEntry = resolveCliEntry(); if (!cliEntry) { fail( `'${PINNED_PACKAGE}' not found in any standard node_modules location. ` + `Install it first: npm install -g ${PINNED_PACKAGE}@${REQUIRED_VERSION}`, ); } process.argv = [process.execPath, cliEntry, ...cliArgs]; try { require(cliEntry); } catch (err) { fail(`Failed to invoke ${PINNED_PACKAGE}: ${err && err.message ? err.message : err}`); }Technical Analysis
The launcher includes
process.cwd()/node_modulesamong the trusted package roots and subsequently executes the resolved CLI throughrequire(). The current working directory can be controlled by the caller or influenced by the directory from which an agent invokes the Skill.Although the launcher declares
REQUIRED_VERSION = '3.3.1', it never reads the resolved package'spackage.json, compares its version with the required version, or verifies package integrity. The constant is only used in help and error mes ...[truncated 1888 chars]- Remediation
View remediation
Remediation Suggestions
- Remove
process.cwd()/node_modulesfrom the candidate roots. Do not load executable dependencies from caller-controlled directories. - Resolve the package only from a dedicated, administrator-controlled installation root or bundle the reviewed dependency with a lockfile.
- Read the resolved package's
package.jsonand require an exact version match with3.3.1before loading its CLI. - Canonicalize the package root and CLI path with
fs.realpathSync()and verify that the resulting path remains beneath the approved installation directory. - Reject symbolic links or other path redirections that escape the trusted root.
- Verify the installed package against a pinned cryptographic integrity value, such as the expected npm tarball integrity hash.
- Prefer running the third-party converter in a restricted subprocess or sandbox with narrowly scoped filesystem and network permissions rather than loading it into the agent process.
- Remove
