T08 · Insecure Dependencies
- Location
scripts/parse.js:24- Finding
Unpinned Dependency Installation During Normal Execution
- Content
View full analysis
Vulnerability Details
File Location:
scripts/parse.js, lines 24–37
Vulnerability Type: Unsafe runtime installation of an unpinned third-party dependency
Risk Level: HighVulnerable Code
js // Resolve gray-matter: prefer local install, fall back to global let matter; try { matter = require('gray-matter'); } catch { // Try installing locally in the scripts directory const { execSync } = require('child_process'); const scriptsDir = __dirname; try { execSync('npm install gray-matter', { cwd: scriptsDir, stdio: 'ignore' }); matter = require(path.join(scriptsDir, 'node_modules', 'gray-matter')); } catch (e) { console.error('Error: gray-matter is not installed. Run: npm install gray-matter'); process.exit(1); } }The same unsafe installation procedure is explicitly documented in
SKILL.md, lines 104–112:markdown ## Script Installation The script auto-installs gray-matter via `npm install gray-matter` on first run. If auto-install fails, run manually: ```bash cd <skill-dir>/scripts && npm install gray-mattertext ### Technical Analysis When `gray-matter` cannot be resolved, invoking the parser automatically executes `npm install gray-matter`. The package has no exact version constraint, and the project contains no reviewed lockfile or integrity metadata. Consequently, npm resolves the package and its transitive dependency graph from the registry configured in the execution environment at runtime. This makes normal document parsing dependent on mutable external supply-chain content. npm may also execute dependency lifecycle scripts during installation. Such scripts run with the privileges of the user or Agent invoking this Skill. Immediately after installation, the downloaded package is loaded into the same Node.js process. Although the command itself contains no attacker-controlled shell interpolation, its remote package resolution and implicit execution create a supply-chain risk. The behavior ...[truncated 1776 chars]- Remediation
View remediation
Remediation Suggestions
-
Remove automatic package installation from runtime parsing logic. If the dependency is absent, terminate with a clear installation error.
-
Add a
package.jsonthat declares an exact, reviewedgray-matterversion rather than a floating version or range. -
Generate and commit a lockfile containing the complete dependency graph and integrity hashes.
-
Install dependencies as a separate deployment step using:
bash npm ci --ignore-scripts -
If lifecycle scripts are genuinely required, review them and explicitly allow them in a controlled build environment rather than during Skill execution.
-
Use a trusted registry and enforce registry configuration in the build environment. Consider an internal dependency mirror with package allowlisting.
-
Run dependency vulnerability and provenance checks in CI, and update dependencies only through reviewed changes.
-
Execute the Skill with least privilege, minimal environment variables, restricted filesystem access, and limited network access.
-
Update
SKILL.mdto remove instructions recommending automatic or unconstrained installation.
A safer failure path would resemble:
js let matter; try { matter = require('gray-matter'); } catch { console.error( 'Error: gray-matter is not installed. Install the locked dependencies with npm ci.' ); process.exit(1); }-
