T08 · Insecure Dependencies
- Location
SKILL.md:256- Finding
Unpinned Jest Execution Through npx in CI
- Content
View full analysis
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: MediumVulnerable 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" fiThe 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 jestwithout requiring a trusted local Jest installation, pinned package version, immutable lockfile installation, or no-download option. Depending on the npm/npx version and environment,npxcan 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
- A repository adopts the documented GitHub Actions example.
- The CI runner does not contain a trusted, locally installed Jest executable.
- The workflow executes
npx jest .... npxresolves or downloads the executable package through the configured npm registry.- If that resolution channel or package is compromised, attacker-controlled package or executable code runs on the CI runner.
- The mal ...[truncated 824 chars]
- Remediation
View remediation
Remediation Suggestions
-
Declare Jest as a pinned development dependency and commit the package lockfile.
-
Install dependencies using an immutable command such as:
bash npm ci -
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 ... -
Add an explicit CI check that fails if the expected local executable is absent rather than allowing runtime package retrieval.
-
Pin third-party GitHub Actions to immutable commit SHAs and apply registry allowlisting or an approved internal proxy where appropriate.
-
Use lockfile integrity checks, dependency review, and package provenance verification.
-
Restrict CI permissions and secrets according to least privilege so that compromise of a test dependency has limited impact.
-
When passing selected tests, prefer a safely structured argument mechanism rather than constructing a shell command from a whitespace-delimited string.
-
