T08 · Insecure Dependencies
Warning
- Location
- SKILL.md:256
- Finding
- Unpinned Jest Execution Through npx in CI## Vulnerability Details **File Location**: `SKILL.md`, lines 256–261; operational CI example at lines 293–297 **Vulnerability Type**: Supply-chain exposure through unpinned executable dependency resolution **Risk Level**: Medium ### Vulnerable Code ```bash # For Jest JEST_TESTS=$(echo "$UNIQUE_TESTS" | grep -E '\.(test|spec)\.(ts|js|tsx|jsx)$' | tr '\n' ' ') if [ -n "$JEST_TESTS" ]; then echo "Jest command:" echo " npx jest --passWithNoTests $JEST_TESTS" fi ``` The generated command is then demonstrated as an operational CI step: ```yaml - name: Run affected tests if: steps.tests.outputs.count > 0 run: npx jest $(cat affected-tests.txt | tr '\n' ' ') ``` ### Technical Analysis The documented CI workflow invokes `npx jest` without requiring a trusted local Jest installation, pinned package version, immutable lockfile installation, or no-download option. Depending on the npm/npx version and environment, `npx` can resolve and download Jest when the executable is unavailable locally. This creates a supply-chain trust boundary at execution time: the code executed by CI may be determined by the package registry and current dependency-resolution state rather than solely by reviewed and locked repository content. A registry compromise, package-account compromise, registry substitution, or unintended package resolution could therefore cause unreviewed code to run. This finding does not establish that Jest itself is malicious. The weakness is the documented use of dynamic, unpinned executable resolution in an automated environment. ### Attack Path 1. A repository adopts the documented GitHub Actions example. 2. The CI runner does not contain a trusted, locally installed Jest executable. 3. The workflow executes `npx jest ...`. 4. `npx` resolves or downloads the executable package through the configured npm registry. 5. If that resolution channel or package is compromised, attacker-controlled package or executable code runs on the CI runner. 6. The mal ...[truncated 824 chars]
- Remediation
- ## Remediation Suggestions 1. Declare Jest as a pinned development dependency and commit the package lockfile. 2. Install dependencies using an immutable command such as: ```bash npm ci ``` 3. Invoke only the repository-local executable and prohibit implicit downloads, for example: ```bash npm exec --no -- jest --passWithNoTests ... ``` Alternatively: ```bash ./node_modules/.bin/jest --passWithNoTests ... ``` 4. Add an explicit CI check that fails if the expected local executable is absent rather than allowing runtime package retrieval. 5. Pin third-party GitHub Actions to immutable commit SHAs and apply registry allowlisting or an approved internal proxy where appropriate. 6. Use lockfile integrity checks, dependency review, and package provenance verification. 7. Restrict CI permissions and secrets according to least privilege so that compromise of a test dependency has limited impact. 8. When passing selected tests, prefer a safely structured argument mechanism rather than constructing a shell command from a whitespace-delimited string.
