依赖审计 Agent
🎯 学习目标
- 解析 monorepo 多包 lockfile 依赖树
- 对接 OSV/GitHub Advisory 查 CVE 并映射 CVSS
- 以 MCP Tool 暴露 audit_dependencies 供 Agent/CI 调用
引言
与 3.5 理论呼应,本课逐步实现可被 Cursor Agent 调用的 MCP 审计服务,输出 JSON + Markdown 报告。
章节正文
第 1 步:第 1 步:扫描依赖
python
import json, subprocess, pathlib
def parse_package_lock(root: pathlib.Path):
lock = root / "package-lock.json"
if not lock.exists():
return []
data = json.loads(lock.read_text())
pkgs = []
for name, meta in data.get("packages", {}).items():
if name == "": continue
ver = meta.get("version")
pkgs.append({"name": name.split("node_modules/")[-1], "version": ver})
return pkgsPython 项目同理解析 poetry.lock / requirements.txt。
第 2 步:第 2 步:CVE 查询
python
import httpx
def query_osv(package: str, version: str):
resp = httpx.post("https://api.osv.dev/v1/query", json={
"package": {"name": package, "ecosystem": "npm"},
"version": version,
}, timeout=30)
return resp.json().get("vulns", [])映射 severity:CVSS ≥9 → critical,≥7 → high。
第 3 步:第 3 步:生成报告
python
def audit_dependencies(project_path: str) -> dict:
pkgs = parse_package_lock(pathlib.Path(project_path))
findings = []
for p in pkgs:
for vuln in query_osv(p["name"], p["version"]):
findings.append({"package": p["name"], "version": p["version"], "id": vuln["id"]})
return {
"summary": {"total": len(pkgs), "vulnerabilities": len(findings)},
"findings": findings,
"markdown": format_md(findings),
}第 4 步:第 4 步:MCP Server 暴露
使用 @modelcontextprotocol/sdk 或 Python mcp 包注册 tool:
json
{
"name": "audit_dependencies",
"description": "审计项目依赖 CVE,参数 project_path",
"inputSchema": { "type": "object", "properties": { "project_path": { "type": "string" } } }
}CI:audit → critical>0 → fail build。Cursor 中 Agent 可说「审计当前仓库依赖」。
动手练习
- 对含已知漏洞的旧版 lodash 项目跑 audit
- 输出 Markdown 表格含 severity 列
- 在 CI 添加 audit job
本节小结
lockfile 解析 → OSV 查询 → 结构化报告 → MCP Tool;CI 门禁 critical 漏洞。