mcpField
D
dependencies-audit

dependencies-audit

github.com/cognitedata安全236 次安装
代码仓库

关于 dependencies-audit

用于审查和修复项目依赖问题的技能,面向需要准备 Dune 应用审查材料的开发者。它检查版本、安全漏洞、维护状况、供应链风险和许可证,并生成 `review-packages.md` 及未解决事项摘要。

主要功能

  1. 01盘点依赖并查询 npm 元数据
  2. 02检查并修复已知安全漏洞
  3. 03评估依赖健康状况与弃用情况
  4. 04审查安装脚本和供应链风险
  5. 05检查许可证并生成审查报告

适用场景

  1. 01审计项目依赖中的漏洞与过期版本
  2. 02查找弃用或维护状况不佳的依赖
  3. 03为 Dune 应用审查生成依赖清单

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/cognitedata/dune-skills --skill dependencies-audit

安装后在 Claude Code 中输入/dependencies-audit确认已加载。

详细介绍

依赖项修复

查找并修复 $ARGUMENTS 中(如果未提供参数,则为根目录 package.json)的所有依赖项问题,包括漏洞、过时的软件包、已弃用的依赖项、许可证问题和供应链风险。此技能会生成 Dune 应用审核流程所需的 review-packages.md 文件。


步骤 1 — 读取并列出所有依赖项

# List all dependencies and devDependencies
node -e "
  const pkg = require('./package.json');
  console.log('=== Dependencies ===');
  Object.entries(pkg.dependencies || {}).forEach(([name, ver]) => console.log(name + ' @ ' + ver));
  console.log('\\n=== Dev Dependencies ===');
  Object.entries(pkg.devDependencies || {}).forEach(([name, ver]) => console.log(name + ' @ ' + ver));
"

记录 dependencies 和 devDependencies 的依赖项总数。


步骤 2 — 查询 npm 元数据并更新过时的软件包

对每个软件包,收集以下信息:

  • npm 上的最新版本
  • 每周下载量
  • 最近发布日期
  • 是否已弃用
# Batch lookup — run for each package (example for a single package)
npm view <package-name> --json 2>/dev/null | node -e "
  const data = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
  console.log(JSON.stringify({
    name: data.name,
    latest: data['dist-tags']?.latest,
    modified: data.time?.modified,
    deprecated: data.deprecated || false,
  }));
"

# For weekly downloads, use the npm API
curl -s "https://api.npmjs.org/downloads/point/last-week/<package-name>" | node -e "
  const data = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
  console.log(data.downloads);
"

为提高效率,请批量查询多个软件包。如果项目的依赖项较多,请使用脚本:

node -e "
  const { execSync } = require('child_process');
  const pkg = require('./package.json');
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };

  for (const [name, usedVersion] of Object.entries(allDeps)) {
    try {
      const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' }));
      const latest = info['dist-tags']?.latest || 'unknown';
      const modified = info.time?.modified || 'unknown';
      const deprecated = info.deprecated ? 'YES' : 'No';
      console.log([name, usedVersion, latest, modified, deprecated].join(' | '));
    } catch {
      console.log(name + ' | ' + usedVersion + ' | LOOKUP FAILED');
    }
  }
"
修复:更新过时的软件包

对于落后超过 1 个主版本的软件包,请更新它们:

pnpm update <package>@latest

对于落后 1 个或更多次小版本的软件包,请更新到最新的小版本:

pnpm update <package>

更新后,运行 pnpm install 和 pnpm run build,验证没有问题。如果主版本更新导致构建失败,请回退该特定更新,并将其记录为需要手动修复的事项。


步骤 3 — 运行安全审计并修复漏洞

# Run audit with the project's package manager
pnpm audit --json 2>/dev/null || npm audit --json 2>/dev/null

# Also run production-only audit (what ships to users)
pnpm audit --prod --json 2>/dev/null || npm audit --production --json 2>/dev/null

解析 JSON 输出,获取以下信息:

  • 按严重程度统计的数量(critical、high、moderate、low)
  • 每个漏洞的详细信息(软件包、严重程度、标题、已修补版本、公告 URL)

任何存在已知 CVE 的软件包,在健康状况列中都应自动标记为 Fail。

修复:解决漏洞

运行 pnpm audit fix,自动修复可修复的问题。对于无法自动修复的剩余高危/严重 CVE,请在 package.json 中手动将存在漏洞的软件包更新到已修补版本,然后运行 pnpm install。如果已修补版本有破坏性变更,请进行适配所需的最小代码改动。如果漏洞存在于传递依赖中,请在 package.json 中使用 pnpm overrides 强制指定已修补版本:

{
  "pnpm": {
    "overrides": {
      "vulnerable-package": ">=2.1.0"
    }
  }
}

应用修复后,重新运行 pnpm audit,确认漏洞已解决。运行 pnpm run build,验证没有问题。


步骤 4 — 评定健康状况并修复被评为 Fail 的软件包

为每个软件包分配一个健康状况指示:

健康状况标准
Pass每周下载量 >100k,且在过去 12 个月内更新过、未被弃用,并且版本为当前版本或接近当前版本(落后不超过 1 个主版本)
Warn每周下载量为 10k–100k,或距上次发布已超过 12 个月,或落后超过 1 个主版本
Fail每周下载量 <10k,或 2 年以上未更新,或已弃用,或存在已知 CVE

特殊情况:

  • @cognite/* 软件包:即使下载量较低,也应信任 Cognite 内部软件包
  • @types/* 软件包:信任 DefinitelyTyped 软件包;重点检查版本是否与主软件包匹配
  • 新发布的软件包(发布未满 6 个月):标记为 Warn 以供审核,不要仅因下载量低就自动标记为 Fail
修复:替换被评为 Fail 的软件包

对于每个被评为 Fail 的软件包:

  • 如果已弃用: 查找并安装建议的替代品。更新代码库中的所有导入。
  • 如果未维护(2 年以上): 查找功能相当且仍在积极维护的替代品,并进行替换。
  • 如果下载量低且不属于 @cognite/*: 评估是否确实需要它。如果存在原生 JS/TS 替代方案,或该功能很简单,请移除该依赖项并以内联方式实现。

每次替换后,运行 pnpm install 和 pnpm run build,验证替代品可正常工作。


步骤 5 — 检查供应链风险并采取缓解措施

# Check for install scripts (preinstall, postinstall, prepare)
node -e "
  const { execSync } = require('child_process');
  const pkg = require('./package.json');
  const allDeps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });

  for (const name of allDeps) {
    try {
      const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' }));
      const scripts = info.scripts || {};
      const risky = ['preinstall', 'install', 'postinstall'].filter(s => scripts[s]);
      if (risky.length > 0) {
        console.log('INSTALL SCRIPT: ' + name + ' — ' + risky.join(', '));
      }
    } catch {}
  }
"

# Check for packages with very few maintainers (single point of failure)
# This is informational, not blocking
修复:评估并缓解安装脚本风险

对于包含安装脚本的每个依赖项,请判断脚本是否合法(例如,sharp、esbuild、better-sqlite3 的原生模块编译)。已知构建工具和原生模块软件包预期会包含安装脚本。

如果该软件包不是已知构建工具,且其安装脚本可疑,请将其替换为更安全的替代品。替换后,运行 pnpm install 和 pnpm run build 进行验证。


步骤 6 — 检查许可证兼容性并替换有问题的包

# List all licenses
npx license-checker --summary 2>/dev/null || node -e "
  const { execSync } = require('child_process');
  const pkg = require('./package.json');
  const allDeps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });

  for (const name of allDeps) {
    try {
      const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' }));
      console.log(name + ': ' + (info.license || 'UNKNOWN'));
    } catch {}
  }
"

Dune 应用可接受的许可证(商业分发):

  • MIT、Apache-2.0、BSD-2-Clause、BSD-3-Clause、ISC、0BSD、Unlicense、CC0-1.0

需要法律审查的许可证:

  • GPL-2.0、GPL-3.0、LGPL-2.1、LGPL-3.0、AGPL-3.0、MPL-2.0、EUPL-1.1
  • 任何“UNKNOWN”或缺失的许可证
修复:替换许可证有问题的包

对于 生产依赖项 中使用 copyleft 许可证(GPL、AGPL)或许可证未知的包,请寻找使用 MIT/Apache-2.0 许可证的替代包并将其替换。更新代码库中的所有导入。

对于使用 copyleft 许可证的 devDependencies,风险较低,但仍需标记以供注意。

每次替换后,运行 pnpm install 和 pnpm run build 进行验证。


步骤 7 — 生成 review-packages.md 工件(修复后的状态)

应用所有修复后,重新运行元数据查询,以获取修复后的状态。然后按照 Dune 应用审核流程要求的格式生成输出:

## Package audit: [app name]

### Dependencies

| Package | Used version | Latest | Weekly downloads | Last published | Deprecated | CVEs | Health |
| ------- | ------------ | ------ | ---------------- | -------------- | ---------- | ---- | ------ |
| react | ^18.2.0 | 18.3.1 | 25M | 2024-04-26 | No | 0 | Pass |
| some-old-lib | ^1.0.0 | 1.0.3 | 5k | 2021-03-15 | No | 0 | Fail |

### Dev Dependencies

| Package | Used version | Latest | Weekly downloads | Last published | Deprecated | CVEs | Health |
| ------- | ------------ | ------ | ---------------- | -------------- | ---------- | ---- | ------ |
| vitest | ^1.6.0 | 2.0.1 | 8M | 2024-07-01 | No | 0 | Pass |

### Security audit

| Severity | Count |
| -------- | ----- |
| Critical | 0 |
| High | 0 |
| Moderate | 0 |
| Low | 0 |

#### Vulnerabilities

| Package | Severity | Title | Patched in | Advisory |
| ------- | -------- | ----- | ---------- | -------- |
| (none found) | — | — | — | — |

### License summary

| License | Count | Packages |
| ------- | ----- | -------- |
| MIT | 45 | react, react-dom, ... |
| Apache-2.0 | 3 | ... |

### Supply-chain flags

| Package | Risk | Details |
| ------- | ---- | ------- |
| (none found) | — | — |

步骤 8 — 报告剩余问题

总结已修复的问题和尚未解决的问题:

已修复
类别数量详情
已更新的包N包名及版本变更列表
已解决的 CVEN已修复的 CVE 列表
已替换的已弃用依赖项N旧包 -> 新包
已解决的许可证问题N旧包 -> 新包
剩余问题(无法自动修复)

仅列出无法自动修复的问题:

  • 需要手动调整代码的重大版本更新中的破坏性变更
  • 需要法律审查的许可证(例如,传递依赖项中的 LGPL)
  • 没有可用的维护中替代方案的包
  • 尚无已修补版本的漏洞

对于每个剩余问题,说明无法自动修复的原因,以及应用作者需要采取的措施。


完成

说明整体健康状况:修复后 Pass/Warn/Fail 各有多少项,已解决多少个问题,以及应用作者仍需手动处理的事项。

评论

支持 Markdown