mcpField
D
dependencies-audit

dependencies-audit

github.com/cognitedataセキュリティ61.9k 回インストール1 日前に更新
リポジトリ

dependencies-audit について

dependencies-auditは、プロジェクトやルートのpackage.jsonにある依存関係を監査・修正するスキルです。セキュリティ、保守状況、サプライチェーン、ライセンスを確認し、Flowsの審査用review-packages.mdを作成します。

主な機能

  1. 01依存関係のメタデータと更新状況の確認
  2. 02脆弱性の監査と修正
  3. 03健全性評価と問題パッケージの置換
  4. 04インストールスクリプトのリスク確認
  5. 05ライセンス互換性の確認
  6. 06review-packages.mdの生成

活用シーン

  1. 01Flowsアプリの審査資料の準備
  2. 02依存関係の脆弱性の発見と修正
  3. 03商用配布前のパッケージライセンス確認

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/dependencies-auditを入力して読み込まれたか確認します。

詳細

依存関係の修正

$ARGUMENTS(引数が指定されていない場合はルートの package.json)にある依存関係の問題をすべて特定して修正します。脆弱性、古いパッケージ、非推奨の依存関係、ライセンスの問題、サプライチェーンのリスクが対象です。このスキルでは、Flows アプリのレビュー手続きに必要な review-packages.md 成果物を作成します。


Step 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 の合計数を記録します。


Step 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 を実行し、問題が発生しないことを確認します。メジャーアップデートでビルドが失敗する場合は、その更新を元に戻し、手動修正が必要な項目として記録します。


Step 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 を実行し、自動修正できる問題を修正します。自動修正できない high/critical の CVE が残っている場合は、package.json で脆弱なパッケージを修正済みバージョンに手動で更新し、pnpm install を実行します。修正済みバージョンに重大な変更がある場合は、適合に必要な最小限のコード変更を行います。脆弱性が推移的依存関係にある場合は、package.json の pnpm overrides を使用して修正済みバージョンを強制します。

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

修正後、pnpm audit を再実行して脆弱性が解決されたことを確認します。pnpm run build を実行し、問題が発生しないことを確認します。


Step 4 — 健全性スコアを割り当て、Fail と評価されたパッケージを修正する

各パッケージに健全性の指標を割り当てます。

健全性基準
Pass週間ダウンロード数が 10 万を超える、かつ 12 か月以内に更新されている、かつ非推奨ではない、かつバージョンが最新または最新に近い(メジャーバージョンの差が 1 以内)
Warn週間ダウンロード数が 1 万~10 万、または最終公開から 12 か月超、またはメジャーバージョンが 1 つを超えて遅れている
Fail週間ダウンロード数が 1 万未満、または 2 年以上更新されていない、または非推奨、または既知の CVE がある

例外:

  • @cognite/* パッケージ:ダウンロード数が少なくても Cognite 内部パッケージを信頼します
  • @types/* パッケージ:DefinitelyTyped パッケージを信頼し、メインパッケージとバージョンが一致しているかを重視します
  • 公開から 6 か月未満の新しいパッケージ:ダウンロード数が少なくても自動的に Fail とはせず、レビュー対象として Warn を付けます
修正:Fail と評価されたパッケージを置き換える

Fail と評価されたパッケージごとに、以下を行います。

  • 非推奨の場合: 推奨される代替パッケージを探してインストールします。コードベース全体のインポートを更新します。
  • メンテナンスされていない場合(2 年以上): 同等の機能を持つ、積極的にメンテナンスされている代替パッケージを探して置き換えます。
  • ダウンロード数が少なく、@cognite/* ではない場合: 本当に必要かどうかを評価します。ネイティブの JS/TS で代替できる場合、または機能が単純な場合は、依存関係を削除してインラインで実装します。

置き換えのたびに、pnpm install と pnpm run build を実行して、置き換え後も動作することを確認します。


Step 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 を実行して確認します。


Step 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 {}
  }
"

Flows アプリの商用配布で許容されるライセンス:

  • 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」またはライセンス情報がないもの
修正:問題のあるライセンスのパッケージを置き換える

本番依存関係に、コピーレフトライセンス(GPL、AGPL)またはライセンス不明のパッケージがある場合は、MIT/Apache-2.0 ライセンスの代替パッケージを探して置き換えます。コードベース全体のインポートを更新してください。

コピーレフトライセンスのdevDependenciesはリスクが低いものの、認識しておく必要があるため、引き続き指摘してください。

置き換えるたびに pnpm install と pnpm run build を実行して確認します。


Step 7 — review-packages.md アーティファクトを生成する(修正後の状態)

すべての修正を適用した後、メタデータの検索を再実行し、修正後の状態を取得します。次に、Flows アプリのレビュー手順で指定されている形式で出力を作成します。

## 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) | — | — |

Step 8 — 残っている問題を報告する

修正した内容と残っている内容をまとめます。

修正済み
カテゴリ件数詳細
更新したパッケージNパッケージ名とバージョン変更の一覧
解決した CVEN修正した CVE の一覧
置き換えた非推奨の依存関係N古いパッケージ -> 新しいパッケージ
解決したライセンスの問題N古いパッケージ -> 新しいパッケージ
残り(自動修正できなかったもの)

自動修正できなかった問題のみを列挙します。

  • 手動でのコード変更が必要となる、メジャーアップデートによる破壊的変更
  • 法務確認が必要なライセンス(例:推移的依存関係に含まれる LGPL)
  • 保守されている代替パッケージがないパッケージ
  • まだ修正済みバージョンがない脆弱性

残っている項目ごとに、自動修正できなかった理由と、アプリの作成者が行うべきことを説明します。


完了

修正後の全体的な健全性の評価として、Pass/Warn/Fail の件数、解決した問題の件数、およびアプリの作成者による手動対応が必要な項目を示します。

コメント