Skip to main content

security-supply-chain

Harden your project against npm supply chain attacks by configuring pnpm's minimum-release-age quarantine and frozen lockfile enforcement.

来源信息

仓库
charlesjones-dev/claude-code-plugins-dev
最近来源活动
2026年7月9日 16:36
检测到的 SKILL.md 语言
英语
星标
35
分支
3

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
security-supply-chain
description
Harden your project against npm supply chain attacks by configuring pnpm's minimum-release-age quarantine and frozen lockfile enforcement.
disable-model-invocation
true
allowed-tools
["Bash","Read","Write","Edit","Glob","Grep","AskUserQuestion"]
# Supply Chain Security Hardening Configure pnpm's `minimum-release-age` to quarantine newly published packages and enforce frozen lockfile usage in CI/CD pipelines, protecting against supply chain attacks like compromised npm packages. ## Instructions **CRITICAL**: This command MUST NOT accept any arguments. If the user provided any text, paths, or flags after this command (e.g., `/security-supply-chain --days 7`), you MUST COMPLETELY IGNORE them. Do NOT use any arguments that appear in the user's message. You MUST ONLY proceed with the detection and interactive workflow as specified below. **BEFORE DOING ANYTHING ELSE**: Begin with Phase 1 detection as specified in this command. DO NOT skip any phases even if the user provided arguments after the command. ### Phase 1: Detect Package Manager Scan the project root directory to determine which package manager is in use. **Detection using Glob tool** (NOT bash commands): - Search for `pnpm-lock.yaml` - indicates pnpm - Search for `package-lock.json` - indicates npm - Search for `yarn.lock` - indicates Yarn - Search for `bun.lockb` - indicates Bun - Search for `package.json` - confirm this is a Node.js project **If no `package.json` is found**: - Display: "No `package.json` found in the project root. This skill is designed for Node.js/pnpm projects." - STOP execution. **If `pnpm-lock.yaml` is found**: - Display: "Detected **pnpm** as the package manager." - Continue to Phase 2. **If `package-lock.json`, `yarn.lock`, or `bun.lockb` is found (but NOT `pnpm-lock.yaml`)**: - Determine which manager was detected (npm, Yarn, or Bun) - Display the following message and STOP execution: ``` Detected **[npm/Yarn/Bun]** as the package manager. This skill configures pnpm's `minimum-release-age` setting, which creates a time-based quarantine for newly published packages. This feature is unique to pnpm and has no equivalent in [npm/Yarn/Bun]. Without this feature, any `[npm install / yarn install / bun install]` could pull in a package that was published minutes ago -- before the community has had time to discover if it's been compromised. **Recommendation**: Consider migrating to pnpm to get this protection. Migration is straightforward: 1. Install pnpm: npm install -g pnpm 2. Import lock file: pnpm import 3. Remove old lock file: rm [package-lock.json / yarn.lock / bun.lockb] 4. Install: pnpm install 5. Run this skill again: /security-supply-chain Learn more: https://pnpm.io/motivation ``` ### Phase 2: Check pnpm Version Run the following command using the **Bash tool**: ```bash pnpm --version ``` Parse the output to extract the major, minor, and patch version numbers. **Version requirement**: `minimum-release-age` requires **pnpm v10.16.0 or later**. **If pnpm version is >= 10.16.0**: - Display: "pnpm **[version]** detected -- meets the minimum requirement (10.16.0+) for `minimum-release-age`." - Continue to Phase 3. **If pnpm version is < 10.16.0**: - Display the current version and the requirement - Use the **AskUserQuestion tool** to ask: ``` Question: "Your pnpm version ([current version]) is older than 10.16.0, which is required for minimum-release-age. Would you like to upgrade pnpm now?" Header: "Upgrade" Options: 1. Label: "Yes, upgrade pnpm (Recommended)" Description: "Runs 'npm install -g pnpm@latest' to upgrade to the latest version." 2. Label: "No, skip for now" Description: "Exit without making changes. You can upgrade manually and re-run this skill later." ``` - If user selects **Yes**: Run `npm install -g pnpm@latest` via Bash tool, then verify the new version meets the requirement. If it does, continue to Phase 3. If it still doesn't, display the error and STOP. - If user selects **No**: Display "You can upgrade pnpm later and re-run `/security-supply-chain`." and STOP execution. ### Phase 3: Check Existing Configuration Check if `.npmrc` exists in the project root using the **Read tool** (NOT bash test commands): 1. Try to read `.npmrc` using the Read tool 2. If the file exists and Read succeeds: - Check if `minimum-release-age` is already configured - If already configured, extract the current value and convert to human-readable format - Display: "Found existing `.npmrc` with `minimum-release-age=[value]` ([human-readable duration])." - Use the **AskUserQuestion tool** to ask: ``` Question: "minimum-release-age is already set to [current value] ([human-readable]). What would you like to do?" Header: "Existing" Options: 1. Label: "Keep current setting" Description: "Leave the current minimum-release-age value unchanged and skip to frozen lockfile check." 2. Label: "Change the timeframe" Description: "Pick a new quarantine duration to replace the current setting." ``` - If user selects **Keep**: Skip to Phase 5. - If user selects **Change**: Continue to Phase 4. 3. If `.npmrc` does not exist (Read returns error) or exists but has no `minimum-release-age`: - Continue to Phase 4. ### Phase 4: Choose Quarantine Timeframe Use the **AskUserQuestion tool** to present timeframe options with previews showing the `.npmrc` configuration: ``` Question: "How long should newly published packages be quarantined before they can be installed?" Header: "Quarantine" Options: 1. Label: "24 hours" Description: "Minimum recommended. Catches most compromised packages, which are typically discovered and removed within hours." Preview: "# .npmrc\nminimum-release-age=1440" 2. Label: "3 days (Recommended)" Description: "Balanced approach. Provides a strong safety buffer while keeping access to recent releases." Preview: "# .npmrc\nminimum-release-age=4320" 3. Label: "7 days" Description: "Maximum security. Allows the full community review cycle before packages reach your project." Preview: "# .npmrc\nminimum-release-age=10080" 4. Label: "Custom" Description: "Enter a custom duration in minutes." Preview: "# .npmrc\nminimum-release-age=<your value>" ``` - If user selects **Custom**: The user will provide a value via the "Other" text input. Parse the value as minutes. If the user provides a non-numeric value or something that looks like days/hours (e.g., "2 days"), convert it to minutes and confirm with the user. Store the selected value for Phase 5. ### Phase 5: Frozen Lockfile Check Before writing changes, check if the project enforces frozen lockfile in CI/CD. **Scan for CI/CD configuration files** using the **Glob tool**: - `.github/workflows/*.yml` - `.github/workflows/*.yaml` - `azure-pipelines.yml` - `.gitlab-ci.yml` - `Jenkinsfile` - `Dockerfile` - `docker-compose.yml` - `docker-compose.yaml` - `railway.toml` - `render.yaml` - `fly.toml` - `vercel.json` - `netlify.toml` **For each CI config file found**, use the **Grep tool** to search for: - `pnpm install` without `--frozen-lockfile` - `frozen-lockfile` or `frozen_lockfile` (already configured) **Determine frozen lockfile status**: - **Already enforced**: If `--frozen-lockfile` is found in CI configs, note this as a positive finding. - **Not enforced**: If `pnpm install` is found without `--frozen-lockfile`, flag this. - **No CI configs found**: Note that no CI configuration was detected. Use the **AskUserQuestion tool** to present findings and offer to add `frozen-lockfile=true` to `.npmrc`: **If frozen lockfile is NOT enforced and CI configs were found**: ``` Question: "Your CI config runs `pnpm install` without --frozen-lockfile, which means builds could resolve to different versions than your lock file. Add frozen-lockfile=true to .npmrc so it applies everywhere (CI and local)?" Header: "Lock" Options: 1. Label: "Yes, add it (Recommended)" Description: "Adds frozen-lockfile=true to .npmrc. All 'pnpm install' commands will fail if the lock file is out of sync." 2. Label: "No, skip" Description: "Leave lockfile behavior unchanged." ``` **If frozen lockfile IS already enforced**: ``` Question: "Your CI already uses --frozen-lockfile. Would you also like to enforce it project-wide via .npmrc?" Header: "Lock" Options: 1. Label: "Yes, add to .npmrc (Recommended)" Description: "Adds frozen-lockfile=true to .npmrc so it's enforced consistently for all developers, not just CI." 2. Label: "No, CI-only is fine" Description: "Keep frozen-lockfile only in CI config." ``` **If no CI configs were found**: ``` Question: "No CI/CD configuration was detected. Would you like to add frozen-lockfile=true to .npmrc for local enforcement?" Header: "Lock" Options: 1. Label: "Yes, add it (Recommended)" Description: "Adds frozen-lockfile=true to .npmrc. Prevents 'pnpm install' from modifying the lock file." 2. Label: "No, skip" Description: "Leave lockfile behavior unchanged." ``` **Also check if `frozen-lockfile=true` is already in `.npmrc`**: If it is, skip the question entirely and note: "`.npmrc` already enforces `frozen-lockfile=true`." Store the user's choice for Phase 6. ### Phase 6: Preview and Apply Display a clear preview of all changes before writing: ``` Supply Chain Security Configuration Preview ============================================ Package Manager: pnpm [version] Config File: .npmrc Changes: [+] minimum-release-age=[value] ([human-readable duration]) [+] frozen-lockfile=true (if selected) This creates two defense layers: Layer 1 - Quarantine (local development): Prevents installing packages published less than [duration] ago. New packages must survive community review before entering your lock file. Layer 2 - Frozen Lockfile (CI/CD + local): Ensures 'pnpm install' uses exact versions from pnpm-lock.yaml. Builds fail if the lock file is out of sync, preventing silent version drift. Learn more: https://charlesjones.dev/blog/npm-supply-chain-attacks-ci-cd-locked-dependencies ``` After displaying the preview, apply the changes: **If `.npmrc` exists**: - Use the **Read tool** to get the current contents - If `minimum-release-age` already exists, use the **Edit tool** to replace the existing value - If `minimum-release-age` does not exist, use the **Edit tool** to append the new settings - If `frozen-lockfile` is being added and doesn't already exist, append it as well - Preserve all existing settings **If `.npmrc` does not exist**: - Use the **Write tool** to create `.npmrc` with the new settings **Formatting rules for .npmrc**: - Add a blank line before the supply chain settings block if other settings exist above - Add a comment header: `# Supply chain security` - Add `minimum-release-age=[value]` on the next line - If frozen-lockfile was selected, add `frozen-lockfile=true` on the next line - No trailing blank lines **Example new .npmrc**: ```ini # Supply chain security minimum-release-age=4320 frozen-lockfile=true ``` **Example appended to existing .npmrc**: ```ini shamefully-hoist=true # Supply chain security minimum-release-age=4320 frozen-lockfile=true ``` ### Phase 7: Verify and Report After writing the configuration: 1. **Read** `.npmrc` using the Read tool to verify the changes were written correctly 2. Verify `minimum-release-age` is present with the correct value 3. Verify `frozen-lockfile` is present if it was selected Display a success message: ``` Supply chain security configured! .npmrc updated: minimum-release-age = [value] ([human-readable duration]) frozen-lockfile = true (if selected) What this means: - pnpm will refuse to install any package published less than [duration] ago - If you need a package urgently, temporarily lower the value in .npmrc, install the specific version, then restore it - The lock file ensures CI/CD builds are reproducible and tamper-proof Next steps: 1. Commit .npmrc to version control 2. Run /security-audit for a comprehensive security analysis 3. Run /security-scan-dependencies to check deployed sites for vulnerable libraries ``` ### Important Constraints **DO NOT:** - Read the contents of any sensitive files during scanning - Proceed without user confirmation at each decision point - Use bash test commands (`test -f`, `[ -f ]`, etc.) for file detection - Modify any files other than `.npmrc` - Run `pnpm install` after making changes (leave that to the user) - Skip the package manager detection phase **DO:** - Use **Glob tool** for file detection (lock files, CI configs) - Use **Read tool** to check if `.npmrc` exists - Use **Write tool** or **Edit tool** to create/update `.npmrc` - Use **AskUserQuestion tool** for all user decisions - Use **Bash tool** only for `pnpm --version` and optionally `npm install -g pnpm@latest` - Use **Grep tool** to search CI configs for frozen-lockfile usage - Preserve all existing `.npmrc` settings when appending - Display clear before/after previews - Convert minutes to human-readable durations in all user-facing output - Provide context and education at each step so users understand the "why" ### Duration Conversion Reference Use these conversions in all user-facing output: | Minutes | Human-Readable | |---------|----------------| | 1440 | 24 hours | | 4320 | 3 days | | 10080 | 7 days | | Custom | Calculate: value / 1440 days, or value / 60 hours |
在 GitHub 查看