Skip to content
Qi edited this page Aug 3, 2026 · 6 revisions

欢迎来到 npm-safe Wiki(中文版)

英文版首页:English Home

@npm-safe 是一个本地优先的引擎,用于分析 npm 包是否符合已知的供应链攻击模式。它从公共 npm 注册表获取包元数据,对元数据和 README 内容执行静态分析规则,将结果缓存到本地 SQLite 数据库,并提供类型化的 API 用于查询、监控和刷新安全评估。该引擎设计为以库的形式运行,而非独立服务。

目录

项目状态

第一阶段已完成(引擎核心)+ 第二阶段已完成。

  • 引擎核心交付,29 个源文件,零 TypeScript 错误。
  • 第二阶段新增完整测试套件(247 个测试全部通过)、CLI 命令行工具、代理支持、可选的多后端 LLM 扫描提供者,以及基于 Neutralinojs 的桌面 GUI。
  • 2026-08-02 完成一轮安全加固,修复漏洞排查发现的 12 个问题,包括桌面 GUI 中两处严重的 XSS 到 RCE 漏洞(所有字段现已转义)、监控列表刷新崩溃,以及 -j 输出标志、亚秒级 TTL 精度等 CLI 正确性问题。
  • CI/CD 集成已发布:npm-safe ci 命令 + GitHub Actions 工作流。

功能简介

  1. 获取 — 从公共 npm 注册表获取包元数据(支持重试、退避与代理)。
  2. 静态分析 — 对元数据和 README 内容执行纯静态分析规则(扫描过程不发起网络请求)。
  3. 缓存结果 — 缓存到本地 SQLite 数据库(WAL 模式、基于 TTL 的缓存)。
  4. 类型化 APINpmSafeEngine 类提供检查、搜索、监控和刷新安全评估的完整接口。

快速上手

前置条件

  • Node.js 18 或更高版本(需要全局 fetch
  • pnpm 9 或更高版本

安装与配置

pnpm install
pnpm -F @npm-safe/core exec tsc --noEmit

TypeScript 编译器(tsc)作为每个包的 devDependency 安装在 pnpm 的隔离存储中,不会提升至工作区根目录,因此在顶层运行 npx tsc 会失败。请使用 pnpm -F @npm-safe/core exec tsc --noEmit

构建并链接 CLI

pnpm -F @npm-safe/core run build
cd packages/core && npm link

快速检查

npm-safe check lodash

示例输出:

包名: lodash
最新版本: 4.18.1
安全等级: suspicious
分数: 65/100
发现项: 5
...

CLI 命令参考

npm-safe <package>                 # check 的简写
npm-safe check <package>           # 检查包的安全性
npm-safe search <query>            # 搜索 npm 注册表
npm-safe watch list                # 查看监控列表
npm-safe watch add <package>       # 添加监控
npm-safe watch remove <package>    # 移除监控
npm-safe refresh [package]         # 刷新单个(或全部监控)包
npm-safe settings get <key>        # 读取设置
npm-safe settings set <key> <val>  # 写入设置
npm-safe lang [en|zh]              # 查看或设置输出语言
npm-safe rules list                # 列出扫描规则及生效状态
npm-safe rules enable <rule-id>    # 启用扫描规则(持久化)
npm-safe rules disable <rule-id>   # 禁用扫描规则(持久化)
npm-safe rules severity <rule-id> <severity>  # 覆盖规则严重级别
npm-safe llm status                # 查看 LLM 提供者状态
npm-safe llm enable                # 启用 LLM 扫描
npm-safe llm disable               # 禁用 LLM 扫描
npm-safe llm set-provider <openai|gemini|anthropic>
npm-safe llm set-key <api-key>     # 设置 LLM API 密钥
npm-safe llm set-model <model>     # 设置 LLM 模型
npm-safe llm test-connection       # 测试 LLM 连接
npm-safe ci                        # 扫描依赖,严重问题时使构建失败

全局选项

  • -d, --db <path> — 自定义 SQLite 数据库路径(默认 ~/.npm-safe/npm-safe.db
  • -p, --proxy <url> — 注册表请求的 HTTP 代理
  • -j, --json — JSON 输出
  • -v, --version — 版本号

桌面应用

packages/desktop/ 下提供基于 Neutralinojs 的桌面 GUI。开发模式运行:

cd packages/desktop
pnpm run run

构建发布包:

pnpm run build

功能特性:

  • 总览仪表盘 — 平均安全评分半圆仪表、近 7 日检查柱状图、总检查次数、风险分布、最近检查列表。
  • 检查 — 输入包名,查看安全等级、分数和详细发现项。
  • 搜索 — 关键词搜索 npm 注册表;点击结果直接跳转检查。
  • 监控 — 管理监控列表,刷新单个或全部监控包。
  • 评价体系 — 列出所有规则,启用/禁用每条规则、覆盖严重级别、重新加载插件规则。
  • LLM — 配置可选 LLM 扫描(启用开关、提供者、API 密钥、模型、基础 URL),提供测试连接按钮。
  • 设置 — 读取/写入任意引擎设置(如 proxylang)。
  • 浅色/深色主题 — 两套独立的 Material You 配色,跨会话记忆。
  • 自定义窗口边框 — 无边框窗口,支持标题栏拖动、最小化和关闭按钮。
  • 持久化检查历史 — 存储于 ~/.npm-safe/history.json(上限 1000 条)。

Windows 首次运行注意:若 WebView2 窗口因回环隔离错误无法加载,请以管理员身份运行一次 PowerShell:

CheckNetIsolation.exe LoopbackExempt -a -n="Microsoft.Win32WebViewHost_cw5n1h2txyewy"

代理配置

在受限网络中,注册表可能只能通过代理访问。代理解析优先级:--proxy 参数 > 持久化的 proxy 设置 > HTTPS_PROXY / HTTP_PROXY / ALL_PROXY 环境变量。NO_PROXY 变量(精确匹配、.后缀 匹配或 *)可绕过代理。

# 持久化代理(推荐)
npm-safe settings set proxy http://127.0.0.1:7897

# 或每次调用时传入
npm-safe --proxy http://127.0.0.1:7897 check react

语言切换

npm-safe lang          # 查看当前语言
npm-safe lang zh       # 切换为中文(持久化)
npm-safe lang en       # 切换为英文(持久化)

规则与插件

扫描规则可在运行时管理,配置持久化在 ~/.npm-safe/rules.json

npm-safe rules list                          # 查看所有规则及状态
npm-safe rules disable install-script        # 禁用规则
npm-safe rules enable install-script         # 重新启用
npm-safe rules severity typosquatting critical  # 覆盖规则严重级别

第三方规则插件可放入 ~/.npm-safe/rules/ 目录(*.mjs / *.js ES 模块文件)。每个文件可导出 rulerulesdefault,内容为一个或多个符合 ScanRule 接口的规则:

// ~/.npm-safe/rules/my-rule.mjs
export const rule = {
  id: "my-rule",
  name: "My rule",
  description: "Detects something bad",
  severity: "high",
  category: "informational",
  enabled: true,
  match(readme, packageJson) {
    return packageJson?.scripts?.postinstall?.includes("wget")
      ? [{ ruleId: "my-rule", ruleName: "My rule", severity: "high",
           message: "postinstall uses wget", category: "informational" }]
      : [];
  },
};

插件文件在引擎启动时自动加载,损坏的文件会被跳过。ScanRule 接口及完整的引擎规则 API(registerRuleunregisterRulelistRulessetRuleEnabledsetRuleSeverity)均从 @npm-safe/core 导出。

LLM 扫描

基于 LLM 的语义扫描是可选功能,默认禁用。当未配置 API 密钥时,静态分析照常运行。配置持久化在 ~/.npm-safe/llm.json,也可通过环境变量提供(OPENAI_API_KEYGEMINI_API_KEYANTHROPIC_API_KEY)。

npm-safe llm status                 # 查看当前状态
npm-safe llm enable                 # 开启 LLM 扫描
npm-safe llm set-provider openai    # 选择提供者
npm-safe llm set-key $OPENAI_API_KEY
npm-safe llm set-model gpt-4o-mini
npm-safe llm test-connection        # 验证连接

CI/CD 集成

npm-safe ci 扫描项目的直接依赖,当任一依赖达到可配置的安全级别时使构建失败:

npm-safe ci --dir ./packages/core          # 默认失败级别:dangerous
npm-safe ci --fail-level suspicious        # 更严格的阈值
npm-safe ci --prod                         # 跳过 devDependencies
npm-safe ci --json                         # 输出机器可读报告
npm-safe ci --rate-limit 50                # 每秒注册表请求数

退出码:0 通过,1 用法/配置错误,2 有依赖达到失败级别(或扫描出错)。仓库自带可直接使用的 GitHub Actions 工作流(.github/workflows/ci.yml)——每次 push/PR 自动运行测试套件、类型检查与依赖安全扫描。

架构设计

引擎由五层组成,每层仅依赖其下方的层。index.ts 门面层组合所有依赖并将结果暴露为单一的 NpmSafeEngine 类。

                           +-----------------------+
                           |      index.ts          |
                           |  NpmSafeEngine 门面    |
                           |  24 个公共方法          |
                           +-----------+-----------+
                                       |
              +------------------------+------------------------+
              |                        |                        |
     +--------v--------+     +---------v---------+     +--------v--------+
     |   Registry      |     |    Scanner        |     |   Scheduler     |
     |  NpmRegistryClient|   |  StaticAnalyzer   |     | RefreshScheduler|
     |  Validator       |     |  10 条规则         |     |  TokenBucket    |
     |  (HTTP 请求)     |     |  (纯分析)          |     |  (速率限制)      |
     +--------+---------+     +---------+---------+     +--------+--------+
              |                          |                        |
              |                          |                        |
              +--------------------------+------------------------+
                                         |
                                +--------v--------+
                                |     Store       |
                                | DatabaseManager |
                                |  CacheManager   |
                                |  SQLite (WAL)   |
                                +-----------------+

各层职责

层级 模块 职责
Registry(注册表层) registry/client.tsregistry/validator.tsregistry/types.ts 与 npm 注册表 API 进行 HTTP 通信,获取包数据、验证包名和版本、定义注册表相关类型。
Scanner(扫描器层) scanner/static-rules.tsscanner/rule-config.tsscanner/rule-loader.tsscanner/types.ts 对包元数据和 README 内容进行纯静态分析。十条内置规则 + 运行时规则注册、配置覆盖和插件发现。
Scheduler(调度器层) scheduler/refresh-scheduler.tsscheduler/rate-limiter.ts 管理被监控包的定时刷新周期。令牌桶(5 tokens/s, 10 burst)限制注册表请求频率。
Store(存储层) store/database.tsstore/cache-manager.tsstore/schema.ts 基于 better-sqlite3 的持久化存储,WAL 模式。处理迁移、TTL 缓存、监控列表持久化和键值设置。
Facade(门面层) index.ts NpmSafeEngine 类组合上述四层,暴露 24 个公共方法:checkPackagesearchPackages、监控列表 CRUD、刷新操作、设置访问、规则管理、LLM 配置及生命周期管理。

第六层为辅助层 Translator(翻译器),提供可插拔的翻译接口,用于将发现结果和摘要转换为不同语言。

关键设计决策

决策 理由
仅 ESM"type": "module" 与现代 Node.js 生态系统保持一致,所有导入使用 .js 后缀。
严格 TypeScript,禁止 any 每个函数和接口均完整类型化,以 --strict 编译,零隐式 any
每模块 250 行代码上限 确保每个文件职责集中、便于审查。
使用 better-sqlite3 的 SQLite 零配置嵌入式数据库,启用 WAL 模式、busy_timeout=5000synchronous=NORMAL 和外键约束。
纯静态分析(无网络请求) 扫描器仅检查已获取的元数据和 README 文本,分析过程不发起外部 API 调用。
TokenBucket 速率限制器(5 tokens/s, 10 burst) 防止触发注册表限流。
缓存优先的 checkPackage,基于 TTL 判断过期 TTL 未过期时立即返回缓存结果,过期则触发后台刷新。默认 TTL 为 1 小时。
SecurityLevel / Severity 使用字符串枚举 可安全地记录、序列化及在 switch 语句中使用。
评分机制:100 减去严重性权重 Critical = 25, High = 15, Medium = 8, Low = 3,未评分包默认 100 分(安全)。
等级阈值 >=80 安全,>=50 可疑,>=20 危险,其余为未知。

数据位置

数据 路径
SQLite 数据库 ~/.npm-safe/npm-safe.db
检查历史 ~/.npm-safe/history.json
规则配置 ~/.npm-safe/rules.json
LLM 配置 ~/.npm-safe/llm.json
规则插件 ~/.npm-safe/rules/
扩展日志(桌面端) %TEMP%/npmsafe-extension.log(Windows)/ $TMPDIR/npmsafe-extension.log(macOS/Linux)

未来展望

项目下一步的方向 —— 一些想法与路线图项目,并非全部已承诺:

  • UX/UI 改进 — 打磨桌面 GUI 的 Material You 体验:更流畅的动画、更好的空状态、键盘快捷键以及跨标签页的更响应式布局;改进 CLI 的交互输出与错误信息可读性。
  • 批量操作 — 多包 checkPackage、批量搜索导出,以及仪表盘报告下载。
  • 仪表盘报告 — 生成可分享的安全报告(HTML / JSON),汇总检查历史与风险趋势。
  • 更深入的扫描 — 更多内置静态规则、包依赖的传递性分析,以及离线规则更新。
  • 团队工作流 — 项目级配置文件、组织级监控列表,以及告警钩子。

更多路线图请参见项目 README 的下一步计划章节。

相关文档

许可证

Apache License 2.0

Clone this wiki locally