T08 · Insecure Dependencies
Warning
- Location
- scripts/init-vite.sh:19
- Finding
- Unpinned npm Dependencies and Mutable “Latest” CLI Packages Permit Supply-Chain Code Execution<![CDATA[ ## Vulnerability Details **File Location**: - `scripts/init-vite.sh:19-37` - `scripts/init-vite.sh:333-335` - `scripts/init-nextjs.sh:19-25` - `scripts/init-nextjs.sh:35-48` - `scripts/bundle-artifact.sh:23-45` **Vulnerability Type**: Unpinned third-party dependencies and mutable remote package execution **Risk Level**: Medium ### Vulnerable Code #### `scripts/init-vite.sh:19-37` ```bash # Create Vite project npm create vite@latest "$PROJECT_NAME" -- --template react-ts cd "$PROJECT_NAME" # Create .nvmrc for Node version echo "18" > .nvmrc echo "📦 Installing dependencies..." # Install Tailwind CSS npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p # Install animation library npm install framer-motion # Install shadcn/ui base dependencies npm install tailwindcss-animate class-variance-authority clsx tailwind-merge npm install lucide-react npm install @radix-ui/react-slot ``` #### `scripts/init-vite.sh:333-335` ```bash npx shadcn@latest add button badge card accordion dialog navigation-menu tabs sheet separator avatar alert -y || { echo "⚠️ Warning: Some shadcn components may not have installed. Run 'npx shadcn@latest add [name]' manually." } ``` #### `scripts/init-nextjs.sh:19-25` ```bash npx create-next-app@latest "$PROJECT_NAME" \ --typescript \ --tailwind \ --eslint \ --app \ --src-dir \ --import-alias "@/*" ``` #### `scripts/init-nextjs.sh:35-48` ```bash # Install animation library npm install framer-motion # Install shadcn/ui echo "📦 Initializing shadcn/ui..." npx shadcn@latest init -y -d # Install common components echo "📦 Installing common components..." npx shadcn@latest add button badge card accordion dialog navigation-menu tabs sheet separator avatar alert -y || { echo "⚠️ Warning: Some shadcn components may not have installed. Run 'npx shadcn@latest add [name]' manually." } # Install lucide icons npm install lucide-react ``` #### `scripts/bundle-artifact.sh:23-45` ```bash if ! npm ls p ...[truncated 3482 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Pin every directly executed CLI to an exact reviewed version.** ```bash npm create vite@6.1.0 "$PROJECT_NAME" -- --template react-ts npx --yes shadcn@2.3.0 add button badge card accordion dialog navigation-menu tabs sheet separator avatar alert npx --yes create-next-app@15.1.7 "$PROJECT_NAME" ... ``` 2. **Pin all installed dependencies to exact versions.** Avoid unqualified package names and avoid `@latest`. Record approved versions centrally so updates require explicit review. 3. **Use lockfiles and deterministic installation.** Supply a reviewed `package-lock.json` or generate projects from a version-controlled template containing one, then install with: ```bash npm ci ``` 4. **Review lockfile changes before upgrades.** Treat changes to package versions, resolved registry URLs, integrity hashes, and lifecycle scripts as security-sensitive. 5. **Restrict lifecycle scripts where compatible.** ```bash npm ci --ignore-scripts ``` If a dependency legitimately requires a lifecycle script, document and review that exception rather than enabling scripts globally without inspection. 6. **Use a trusted registry and retain integrity verification.** Configure npm to use an approved HTTPS registry, preserve lockfile integrity hashes, and consider an internal registry or package allowlist for controlled environments. 7. **Separate tooling from generated application dependencies.** Declare bundling tools in a reviewed tooling package with a committed lockfile instead of installing them dynamically when `bundle-artifact.sh` runs. 8. **Run scaffolding in a constrained environment.** Use an unprivileged container or sandbox with minimal filesystem access, no unrelated secrets, and restricted outbound networking. 9. **Add dependency security checks.** Run package provenance checks, vulnerability scanning, and lockfile analysis in CI. These checks supplement version pinning but do not replace it. ...[truncated 182 chars]
