依赖审查

eranw20002026-10-26查看 1349复制 1632

审查分支新增或变更的依赖是否存在已知 CVE、许可证合规、供应链风险及不必要的添加,覆盖 Python(pip/Poetry)、JS/TS(npm/pnpm)和 Java/C#(Maven/Gradle/NuGet)。生成锚定到 SEC-DEP-* 规则的 DEPENDENCY-COMMENTS.md。当 PR 触及清单或锁文件,或用户说“dependency review”、“check dependencies”、“SCA”、“supply chain”、“are these packages safe”、“license check”时使用。

Download (.md)

📘如何使用这个技能

  1. 1
    复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
  2. 2
    打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
  3. 3
    粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
  4. 4
    直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景

💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。

SKILL.md6866 chars
---
model: fable
name: dependency-review
description: Review the dependencies a branch adds or changes for known CVEs, license compliance, supply-chain risk, and unnecessary additions, across Python (pip/Poetry), JS/TS (npm/pnpm), and Java/C# (Maven/Gradle/NuGet). Produces DEPENDENCY-COMMENTS.md anchored to SEC-DEP-* rules. Use when a PR touches a manifest or lockfile, or when the user says "dependency review", "check dependencies", "SCA", "supply chain", "are these packages safe", "license check".
---

# Dependency / Supply-Chain Review

You check what a change pulls into the supply chain. Anchored to SEC-DEP-01 to 05 in
`standards/security-standards.md` and banded per `standards/severity-taxonomy.md`.

## Inputs

1. The diff, focused on manifests and lockfiles: `requirements*.txt`, `pyproject.toml`,
   `poetry.lock`, `package.json`, `package-lock.json`, `pnpm-lock.yaml`, `pom.xml`,
   `build.gradle*`, `*.csproj`, `packages.lock.json`.
2. The available SCA tools: `pip-audit`, `npm audit` / `pnpm audit`, OWASP dependency-check,
   `osv-scanner` if present. Run what is installed; if none is, say so and fall back to checking
   versions against the OSV/GitHub advisory data you can reach.

## Process

### 1. Diff the dependency set
List every added, removed, and version-changed dependency, direct and transitive where the
lockfile shows it. Separate direct adds (a human chose them) from transitive churn (pulled by a
direct change).

### 1b. Every added name exists (SEC-DEP-05)
Run the direct adds from step 1 through the registry check before anything else, because a
name that was never published has no CVEs, no license and no download count, so every later
step would report it clean:

```bash
ci/check-package-exists.py pypi:<name> npm:<name>          # the added names
ci/check-package-exists.py --requirements requirements.txt --package-json package.json
```

Exit 1 is a Blocker: the name is not on the registry, which is how an invented name looks
before an attacker registers it. A name listed as young, or listed as installed from a
configured registry, goes to step 6 as a Question; confirm the second kind on that registry.
Step 6 also asks whether any added name is one edit away from a well-known package; that one
is a reviewer's judgment. Exit 2 means a registry did not answer: record the name
as unconfirmed in the report's Limits section rather than as clean. Exit 2 also covers a
registry reply that is not a document about that name, and a manifest the script could not
read. For an `-r` or `-c` include at a URL, fetch that file and run the script on it.

### 2. Known vulnerabilities (SEC-DEP-01)
Run the SCA tool for each ecosystem present. For each finding, record the advisory ID
(CVE/GHSA/OSV), the affected version, the fixed version, and whether the vulnerable code path is
reachable from this project. Band by reachability and impact, not raw score: a critical CVE on a
reachable path is a Blocker; the same in an unused transitive dep is a Major or Nit. Always name
the fixed version in the fix.

### 2b. Known exploited (SEC-DEP-04)
Take the advisory ids from step 2 and run them through the catalogue:

```bash
ci/check-kev.py CVE-... CVE-...              # ids you already have
pip-audit -r requirements.txt -f json | ci/check-kev.py --pip-audit -
```

A hit outranks its CVSS score. Record the CISA due date and the ransomware flag in the finding,
and band it per SEC-DEP-04: Blocker on a reachable path, Major with a dated reason off one.

The script exits 2, never 0, when it cannot read the catalogue. Treat that as "not checked" and
say so in the report's Limits section rather than letting an unreachable feed read as clean.

### 3. Pinning and provenance (SEC-DEP-02)
Are new dependencies pinned with a committed lockfile? Do they come from the official registry,
or from an arbitrary git ref / URL / tarball (supply-chain risk)? An unpinned or
unofficial-source dependency is a Major.

### 4. License compliance
Check each new dependency's license against the project's own allowlist where it has one, and
where it has none, report the license and raise the question rather than assuming. Copyleft (GPL/AGPL) in a
proprietary product, or a missing/unknown license, is a Major or Question depending on the
company policy. State the license you found.

### 5. Necessity and footprint (SEC-DEP-03)
Does a new dependency duplicate something already in the tree or in the standard library? Is it
a large dependency added for a tiny need? Raise as a Question ("do we need this, or can we use
X already present?"), not an automatic finding.

### 6. Typosquat / integrity smell
Flag names that are near-misses of popular packages, brand-new packages with very low download
counts pulled as direct deps, or a maintainer/scope change on an existing dep. These are
Questions that ask for a human look.

### 7. Write DEPENDENCY-COMMENTS.md

```markdown
# DEPENDENCY REVIEW, <project>

**Branch:** <branch>
**Reviewed at:** <YYYY-MM-DD HH:MM>
**Ecosystems:** <python|node|java|dotnet present>
**Verdict:** BLOCK | APPROVE WITH FIXES | APPROVE

## Dependency changes
- ADD <name>@<version> (direct), license <x>, <one line on why>
- CHANGE <name> <old> -> <new>
- (transitive churn summarized)

## Package names (SEC-DEP-05)
<"all on the registry", or each name not found, each young name with its first-published
date, each name installed from a configured registry and whether you confirmed it there, and
any name left unconfirmed because the run exited 2 (a registry gave no usable answer, or a
manifest or an include at a URL could not be read)>

## Known exploited (SEC-DEP-04)
<CVE, or "none listed", or "not checked: the catalogue was unreachable">
<for each: CISA due date, ransomware flag, reachable yes/no, and the band that follows>

## Blockers
### B-1: <name>@<version>, <CVE/GHSA>
- **Rule:** SEC-DEP-01
- **Advisory:** <id>, affects <range>, fixed in <version>
- **Reachable:** yes/no/unknown, with the call path if known.
- **Fix:** upgrade to <version> (or remove / replace).

## Majors / Questions
(pinning, license, necessity, typosquat smell)

## Limits
Which ecosystems had no SCA tool available, so were checked only by version lookup.
```

### 8. Verdict
- **BLOCK**: a known-vulnerable dependency on a reachable path with a fix available, or a
  name that is not on its registry (SEC-DEP-05).
- **APPROVE WITH FIXES**: Majors (unpinned, license, non-reachable CVE).
- **APPROVE**: clean, with the limits section naming any ecosystem not fully scanned.

## Guardrails

- Do not upgrade dependencies yourself unless the user asks; recommend the target version.
- Name the fixed version for every CVE; "upgrade it" without a version is not a fix.
- Band by reachability, not by CVSS alone. Say when reachability is unknown.
- Respect `baseline.yml` for accepted advisories (with owner + expiry).
来源:skillsdirectory

评论0

登录后参与评论

还没有评论,来抢沙发吧