npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dsh-plugin-security-review

v1.8.1

Published

Static bundle form of the DSH plugin-install security gate: reviews cordis_define/cordis_run with a fail-safe policy, plus review/audit tools and a browser approval popup (agree / agree+whitelist / reject; agree+whitelist writes the plugin family into tru

Readme

Plugin Install Security Review(v1.8.1)

English: README.en.md · 简体中文: 本文档

npm version npm downloads License: MIT

DSH 插件安装安全审查守卫。对 cordis_define / cordis_run 安装或运行的动态插件源码做静态安全审查,并按安全优先策略拦截;同时提供 plugin_security_review / plugin_security_audit 两个审查工具。

v1.5.0 起为静态 bundle 插件,随 profile 层栈自动加载,不再需要每次重启 DSH 后重新 define/run。

仓库内容

| 路径 | 说明 | | --- | --- | | package.json + cordis.patch.yml + lib/ | 静态 bundle(推荐):dsh plugin add 安装后开机自启动 | | manifest.json + package-source.js | 动态插件回退形态(v1.4.0):无 bundle 能力的 profile 按 README 恢复流程加载 | | tests/gate.test.mjs | 动态形态行为测试(node tests/gate.test.mjs) | | tests/static.test.mjs | 静态形态行为测试(node tests/static.test.mjs) |

安装(静态 bundle, 推荐)

dsh plugin --profile web add dsh-plugin-security-review

已发布到 npm(registry.npmjs.org/dsh-plugin-security-review,最新 v1.8.1)。生产环境直接用上述命令从 registry 安装即可;file: 本地安装仅用于未发布或离线调试。

本地未发布时用 file: 指向本仓库(注意路径不能含空格):

dsh plugin --profile web add file:/path/to/dsh-plugin-security-review

重启 dsh web 后守卫即自动生效:plugin_security_audit(无参数)应显示「守卫: 运行中 (v1.8.1)」。

安装(动态插件, 回退)

仅用于没有 bundle 能力的 profile。步骤:

  1. 让 agent 读取 package-source.js 与 manifest.json。
  2. cordis_define:plugin: { kind:"new", idPrefix:"secur" },name/purpose 取 manifest.json,code.host 取 package-source.js 中 return { ... } 之后的内容。
  3. cordis_run 激活;plugin_security_audit 验证。

动态形态不跨 DSH 进程存续,重启后需重新加载;静态 bundle 形态无此限制。

v1.8.1 变更(相对 v1.8.0)

  • 修复: static bundle 的 peerDependencies 对齐 DSH 0.1.1-rc.2。@deepseek-ai/dsh-tools 与 @deepseek-ai/dsh-cordis-host-runner 由 ^0.1.0-rc.6 更新为 ^0.1.1-rc.2,匹配当前 DSH 携带的版本。因 npm/pnpm 对预发布版本严格匹配(预发布版本仅命中范围内相同 major.minor.patch 元组),旧范围不满足 0.1.1-rc.2,会导致 dsh plugin --profile web add/update dsh-plugin-security-review 安装时 peer 校验失败(ERESOLVE)。本版本不影响动态回退形态(不读取 package.json 的 peerDependencies)。

v1.8.0 变更(相对 v1.7.0)

  • 审批弹窗新增「同意+白名单」:弹窗由 [同意][拒绝] 改为 [拒绝] [同意+白名单] [同意]。点「同意+白名单」→ 除把该代码指纹写入 approved 外,还把该插件族加入 trusted-local 白名单(new define 按 idPrefix 写 prefixes;existing/run 按 pluginId 写 pluginIds)——同一插件的安装与开发迭代(code 变更导致指纹变化)不再反复弹窗。点「同意」仍仅批准该代码指纹(代码变更即失效)。白名单写入 best-effort:写失败(权限/损坏)只记日志、不影响指纹批准,读取侧 fail-closed 不变。
  • 修复:点「同意」后重试消息偶发投到别的会话。旧实现用浏览器端单一 sessionId,从 mux 流任意 session/subscribed 帧取值;DSh mux 是全会话聚合的,多会话并存时最后一个订阅者覆盖该值,导致 session.prompt 把重试注入到其它工作对话。现改为守卫在拦截时记录来源会话 id(exec.agent.sessionId,写入每个 pending 条目的 agentId),弹窗点击后经 connection.api.sessions.prompt 注入到来源会话;agentId 缺失或目标不可 prompt 时静默退回手动重试。
  • 弹窗 hint/按钮文案与 README 同步更新;新增 T19(来源会话 id 暴露)与 T20(同意+白名单写白名单、同族变体不再弹窗)测试。
  • 动态回退形态(package-source.js/manifest.json)同步版本号至 v1.8.0,但不提供弹窗(浏览器 GUI 特性,仅静态 bundle;其 ASK 仍走 seam)。

v1.7.0 变更(相对 v1.6.0)

  • 审批弹窗(同意/拒绝, 新增, 静态 bundle):ASK 判定不再走官方审批 seam(在审批禁用部署中 seam 会被策略自动拒绝成 the user rejected tool 死路),改为挂起审批 + deny + 浏览器弹窗。用户点击「同意」→ 代码指纹持久化批准 → 注入会话消息让 agent 自动重试 → 安装/运行成功;点「拒绝」→ 记录并放弃。弹窗经守卫自己的 HTTP 路由(/security-gate/approvals/pending、/security-gate/approvals/decide)轮询驱动,渲染在 shell.overlay 浮层;携带 client/client.js Client 半端(dsh.client 声明 + exports["./client"])。
  • askMode 配置:<DSH_HOME>/storages/plugin-security-gate/config.json 设 {"askMode":"seam"} 可回退官方审批 UI;默认(缺失/损坏)popup。
  • 弹窗样式与主题适配:居中模态 + 半透明遮罩(替代早期侧边浮层, 消除遮挡);全部颜色使用 dsw 设计系统真实令牌(--dsw-alias-bg-overlay/--dsw-alias-button-primary-fill/--dsw-alias-label-primary-foreground/--dsw-alias-bg-mask-3/--dsw-alias-state-error-primary/--dsw-alias-state-warn-label 等),亮/暗主题自动适配,保证字体与窗口可读性。
  • audit 状态展示:总览增加 askMode 与 待审批 数量;gateStatus() 同步新增字段。
  • 动态回退形态版本同步 v1.7.0,但不提供弹窗(浏览器 GUI 特性,仅静态 bundle;其 ASK 仍走 seam),README 明示该差异。

v1.6.0 变更(相对 v1.5.0)

  • 操作者白名单 trusted-local(新增):<DSH_HOME>/storages/plugin-security-gate/trusted-local.json 声明本机可信插件(前缀/pluginId/代码指纹),命中时 cordis_define/cordis_run 直接放行并写入审计历史([trusted-local])。信任锚是有文件权限的操作者,不是 agent 自我声明;文件不存在或损坏时行为与现状完全一致(fail-closed 不变)。cordis_stop/cordis_undefine 的守卫自我保护不受白名单影响。
  • 修复 audit lossless-JSON 报错:plugin_security_audit 不带 includeBundles 时返回 bundles: undefined,违反 dsh-tools 的 lossless-JSON 输出校验导致工具报错;现默认 null。
  • BLOCK 拒绝文案修正:BLOCK 没有人工批准通道,文案不再声称"批准可放行",改指向 trusted-local 白名单;组合规则(HOST_EXFIL_CRED/CLIENT_COOKIE_EXFIL 等)标注 [不可声明削减],明确不受 CAPABILITIES: 声明影响。
  • 动态回退形态(package-source.js/manifest.json)同步到 v1.6.0。

v1.5.0 变更(相对 v1.4.0 动态形态)

  • 静态 bundle 化:命名导出 name/inject/apply,经 ctx.tools.register(defineTool(...)) 注册工具,经 ctx.on('tools/pre-execute') 拦截,开机自启动。
  • 移除动态自升级豁免:静态形态经 dsh plugin update 升级,cordis_define/cordis_run 对所有动态插件一律审查,不再有 secur 前缀/谱系令牌豁免;源码不可检索时一律 fail-closed(ask)。
  • 审查引擎、评分模型、能力声明、跨会话批准持久化、库存审计与 v1.4.0 保持一致。

判定策略(安全优先)

| 判定 | 条件 | 行为 | | --- | --- | --- | | BLOCK | critical>0 或 high≥2 或 总分≥100 | 拒绝安装/运行,附完整报告(不经弹窗) | | ASK | high≥1 或 总分≥40 | askMode=popup(默认):挂起审批 + 弹出「同意/拒绝」确认框,同意后指纹批准并自动重试;askMode=seam:走官方审批服务(审批禁用时等效拒绝) | | WARN | 总分≥10 | 放行,卡片附审查报告 | | ALLOW | 其余 | 放行 |

风险权重:critical=100, high=40, medium=15, low=4,总分上限 300;能力声明项计分减半(最低 1 分)。

审查覆盖面

  • Host 规则:不安全进程执行(exec/execSync/shell:true — critical)、VM 逃逸、Node 内部 API、构造器链逃逸、宿主进程终止(critical);子进程执行能力(spawn/fork — high)、原型污染、动态代码、凭据访问、审批篡改、动态模块加载(high);静态模块加载、进程信号、文件系统、网络、全局设置、沙箱、工具干预、会话读取(medium);普通 env 读取、定时器(low)。
  • 凭据形态环境变量:process.env.X 名字形如 *_KEY/_TOKEN/_SECRET/_PASSWORD/_CREDENTIAL/_AUTH/_COOKIE/_PRIVATE 单独记 high。
  • Client 规则:document.cookie、innerHTML XSS、浏览器 eval、动态模块加载(high);import()/require、存储、网络、跳转、postMessage、Service Worker(medium);host.call、定时器(low)。
  • 15 项服务能力面:ctx.get('shell'/'subprocess'/'credentials'/'approval'/'dynamicCordisRunner'/...) 精确检测。
  • 组合规则(收敛后):凭据形态数据+网络 = critical;Cookie+网络 = critical;文件读取+网络 = high;动态代码+网络 = high;本地存储+网络 = low(信息性)。
  • 混淆检测:高熵长字符串、\x/\u 转义、atob。

能力声明约定(可选)

在 cordis_define 的 purpose 末尾追加:

CAPABILITIES: spawn,network,env,fs

关键字:spawn exec module network env fs credentials approval shell subprocess runner settings sandbox sessions llm process eval vm proto storage cookie dom redirect postmessage serviceworker rpc timer obfs。声明覆盖的规则项计分减半(报告标 [已声明])。

跨会话批准持久化

  • 人工批准的 ASK 成功执行后,其代码指纹(host+client 的 sha256)写入 <DSH_HOME>/storages/plugin-security-gate/state.json。
  • 后续 define/run 命中相同指纹自动放行;代码变更即失效。历史尾部一并持久化。

本地可信开发:trusted-local 白名单(v1.6.0)

背景:守卫对所有 cordis_define/cordis_run 一律审查,合法的本地开发插件也可能被 BLOCK/ASK 卡死(例如"读取 DEEPSEEK_API_KEY 并调用官方 API"这类插件触发 HOST_EXFIL_CRED critical 组合,BLOCK 无人工批准通道)。不做"本地创建自动放行":DSH 工具调用契约里没有来源/出处字段,"本地编写"与"提示注入伪造"在调用面上不可区分,自动放行等于重新引入 v1.4.0 修复过的豁免伪造漏洞。放行必须绑定 agent 自我声明之外的信任锚——操作者文件白名单。

格式(由有文件权限的操作者创建;文件不存在/损坏 = 无白名单,行为不变):

{
  "prefixes": ["dev", "local"],
  "pluginIds": ["devtool-1", "legit-llm-client"],
  "fingerprints": ["<host+client 代码指纹 sha256, 可用 plugin_security_review 结果中的 sha 字段>"]
}

匹配规则(命中任一即直接放行,并记入审计历史 [trusted-local]):

| 条目 | 匹配对象 | | --- | --- | | prefixes | define 的 idPrefix(kind:new)或 pluginId(kind:existing)前缀匹配 | | pluginIds | define 的 pluginId / run 的 pluginId 精确匹配(不依赖源码可检索) | | fingerprints | host+client 联合 sha256 精确匹配(代码变更即失效) |

边界说明:

  • 白名单放行同样适用于 BLOCK 级插件——这是"操作者显式信任"的意图所在。
  • 把守卫自身 id/前缀加入白名单会解除守卫自我保护(操作者本就有文件权限卸载守卫,风险自担)。
  • cordis_stop/cordis_undefine 对守卫的自我保护不受白名单影响。
  • 在 full-access 部署中 agent 也能写该文件——这与 agent 已有全部文件权限的信任级别一致,白名单是对抗"未经操作者确认的高危安装",不是对抗 agent 自身的安全边界。

审批弹窗:拒绝 / 同意+白名单 / 同意(v1.8.0, 静态 bundle)

为什么需要:ASK 判定走官方审批 seam 时,在审批禁用部署(策略自动拒绝)中会变成 the user rejected tool "cordis_define" 死路。v1.7.0 起静态 bundle 形态自带弹窗,ASK 不再无出口。

流程:

  1. cordis_define/cordis_run 触发 ASK 判定 → 守卫挂起审批记录(持久化于 state.json,并记录来源会话 id agentId)并返回 deny,文案提示"已弹出确认框"。
  2. 浏览器端 client/client.js(注册在 shell.overlay 浮层)轮询 GET /security-gate/approvals/pending,弹出卡片:插件名、判定/风险分、风险分布 + [拒绝] [同意+白名单] [同意]。
  3. 点「同意」→ POST /security-gate/approvals/decide {sha, outcome:'approve'} → 守卫把该代码指纹写入 approved → 经 session.prompt 向来源会话注入重试消息 → agent 自动重试 → 同指纹放行。
  4. 点「同意+白名单」→ POST .../decide {sha, outcome:'approveTrusted'} → 同第 3 步外,再把该插件族写入 trusted-local(prefixes/pluginIds)→ 同族后续安装/开发(即使代码变更)直接放行,不再弹窗。
  5. 点「拒绝」→ 记录 human rejected via popup 历史并清除挂起;agent 重试同代码仍被拦截。

配置 askMode(<DSH_HOME>/storages/plugin-security-gate/config.json):

{ "askMode": "seam" }
  • popup(默认,缺失/损坏时回退):守卫自带弹窗;绕过官方审批 UI。
  • seam:走官方 approval 服务(需要部署启用审批,否则等效拒绝)。

边界:

  • 弹窗是浏览器 GUI 特性:仅 web profile 的静态 bundle 形态提供;CLI/无浏览器会话与动态回退形态的 ASK 仍走 seam(deny 文案附 trusted-local 手动指引兜底)。
  • 「同意」仅批准该代码指纹(代码变更即失效),不等于加入 trusted-local;「同意+白名单」才写入 trusted-local。
  • 重试注入固定指向来源会话(entry.agentId,守卫在拦截时从 exec.agent 记录),与当前浏览哪个会话无关;多会话并存不再投错。
  • BLOCK 判定仍硬拒绝,不经弹窗(安全优先不变)。
  • 多会话并存时挂起审批为全局注册表(本地单用户部署通常单会话);如需按会话过滤,后续可在路由增加 session 参数。

profile bundle 库存审计

plugin_security_audit includeBundles=true:扫描 <DSH_HOME>/profiles/* 下声明 dsh 的依赖(@deepseek-ai/* 官方包跳过),读取入口产物做同一套静态审查,输出逐包判定。信息性审计:bundle 安装(pnpm/npm)不经过 cordis_define/cordis_run,守卫无法在该路径硬拦截,仅提供装前/装后可见性。

工具

  • plugin_security_review:对给定 host/client 源码做安装前审查,返回判定、评分、逐条风险与行号;purpose 支持 CAPABILITIES: 声明。
  • plugin_security_audit:指定 pluginId+packageId 出完整报告;无参数出全量总览+拦截/放行历史+守卫状态;includeBundles=true 附加 profile 库存审计。

维护与边界

  • 升级守卫(静态):dsh plugin --profile web update dsh-plugin-security-review;本地 file: 依赖更新后重跑一次 dsh plugin add。
  • 自我保护边界:静态 bundle 守卫无法通过 cordis_stop/cordis_undefine 停用(它不在动态注册表里),但可由有文件权限的操作者经 dsh plugin remove 卸载——这是静态形态与动态形态的固有差异。
  • 已知限制:组合判定是静态 presence 判定,未经数据流确认,可能误报/漏报;深度混淆存在盲区;本守卫是进程内拦截(标准安装路径),不是对抗可停用守卫的恶意 actor 的安全边界,真正的纵深防御仍需宿主级隔离。trusted-local 白名单与审批弹窗都是操作者/用户决策面,不是对抗 agent 自身的安全边界;审批弹窗仅静态 bundle 形态提供。