DSH 本机只读安全审计插件:扫描配置/插件/会话/网络四个维度,输出脱敏、可复现、可定位的风险报告;不修复、不联网、不执行被审计插件。
- 语言
- TypeScript
- License
- MIT
- 分支
- main
安装
$ dsh plugin --profile web add github:omdsh-dev/dsh-security-audit在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 omdsh-dev/dsh-security-audit:先查看仓库 https://github.com/omdsh-dev/dsh-security-audit 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
DSH 本机安全审计工具——以只读方式扫描你的本机 DSH 环境(配置、已装插件、会话文件、网络配置)四个维度的暴露面,输出经过脱敏的结构化风险报告,不自动修复、不联网探测、不执行被审计插件。
核心能力
- 扫描 DSH 配置、profile、凭据文件元数据,发现疑似明文 token/key/私钥、PEM 头,明文永远不进 canonical 输出,只保留 HMAC fingerprint + 路径 + 行号
- 审计已安装插件的来源、加载路径、
cordis.patch.yml行、install 脚本、.env/.pem/.key等敏感文件,以及可选的插件源码危险能力(eval/child_process/网络能力)静态扫描 - 检查会话目录与文件权限、symlink/reparse 逃逸、会话 zstd 帧结构(按帧预算截断以抵挡解压炸弹)
- 检查监听配置、外部 HTTP 明文端点、代理与凭据路由、model discovery 目标,全部仅做配置级分类、不主动连接或探测
- 汇总式
reportaction 把四类扫描合并,输出双维度 verdict:风险维度(fail/warning/pass)+ 覆盖度维度(complete/incomplete),并标记是否因预算截断 - 提供
rulesaction 实时列出 33 条规则的 code / 严重度 / 关键性 / 适用平台
技术实现
- 语言: TypeScript (ESM, strict)
- 关键依赖:
@deepseek-ai/dsh-tools(defineTool注册);@deepseek-ai/cordis(Cordis 容器,inject: ['tools']);@deepseek-ai/dsh-invariants(package 拥有的 invariant companion) - 架构模式: 单一 Cordis 插件注册一个名为
security_audit的工具,通过ctx.tools.register(defineTool({...}))暴露一个多 action 入口,output schema 为 JSON 字符串;通过cordis.patch.yml把security-auditrow 注入宿主 layer stack - 入口文件:
src/index.ts(apply / SecurityAuditConfig),cordis patchcordis.patch.yml,可执行编译入口lib/index.js
适用场景
当你想在把机器借给别人、或新装了一批插件后,核对"本机 DSH 现在的攻击面到底有多大"——比如 DSH 服务是否监听了公网、API key 是否落到过 .env 而非凭据库、刚装的那个插件有没有 install 脚本或可疑能力——就可以跑一次 report 让它一次性给出双维度 verdict 与可定位的 finding 列表。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DeepSeek Harness (DSH) | 0.1.0-rc.8(README 已验证) | README.md:86-94 在 rc.8 隔离 consumer 中完成类型/运行时/工具注册三段验证 |
| Cordis(宿主) | ^4.0.1 | package.json peerDependencies,由 DSH 宿主提供 |
@deepseek-ai/dsh-tools | >=0.0.1-rc.1 <0.2.0 | 提供 defineTool 注册 API |
@deepseek-ai/dsh-invariants | >=0.0.1-rc.1 <0.2.0 | package-owned invariant companion |
| Node.js | ^22.19.0 或 >=24.0.0 | package.json#engines 强制声明 |
| 平台 | macOS / Linux / Windows | 跨平台纯 Node 脚本,仅用 node:fs / node:os / node:path / node:crypto;权限规则在 Windows 上跳过 |
| 原生模块 | 无 | 仅依赖 Node 内置模块,无 native binding |
安装方式
dsh plugin --profile web add github:omdsh-dev/dsh-security-audit
配置项
本插件没有面向用户的运行时配置——所有可见参数都是 security_audit 工具调用入参(action / profile / strict / detail / includeSourceScan / root),由调用方在每次 action 里按需传,不需要预声明。
仅供管理员声明的"宿主层"选项(写在对应 profile 的 cordis.patch.yml 中,作为插件初始化入参传入,普通模型调用无法修改):
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
allowedRoots | string[] | 仅管理员可声明的额外可扫描根路径;模型参数 root 必须等于 $DSH_HOME 或此处列出的路径之一,无法利用此字段外扩读取范围 | 未声明则为空,仅 $DSH_HOME |
allowedEndpoints | string[] | 仅管理员声明的 endpoint 精确白名单(normalized scheme+host+port,无 wildcard/路径/userinfo) | 未声明则为空,全部走默认风险规则 |
普通用户不需要写这两项;它只在管理员有意让审计覆盖多根目录或多端点环境时使用,详见 src/index.ts:29-42 / src/types.ts:136-156。
常见问题
Q: 输出的报告里会出现明文密钥吗?
A: 不会。Redactor 用进程内随机 32 字节 HMAC key 把每个疑似秘密转成 16 进制指纹,原始值只用于指纹计算、不写入 canonical 输出、不出现在错误消息或日志里(src/redact.ts:83-115);并且所有 secret evidence 都强制带 redacted: true 作为协议字段(不是截断提示)。即使 root 覆盖到了含明文的文件,报告里你只会看到"文件/行号/类型/长度/fingerprint"。
Q: 报告会修改本机任何文件吗?
A: 不会。设计层就保证只读:所有路径先 lstat(拒绝 symlink/reparse)→ realpath → containment 检查,root 固定为进程启动时解析的 $DSH_HOME,模型参数不能扩大读取范围;plugin 自己不执行 child_process、不去碰 ACL、不安装任何依赖。源码能力扫描也是纯静态正则匹配——你可以随手 strings lib/index.js | grep chmod 自我验证。
Q: 为什么 scan_network 没有去做实际端口探测?
A: 这是有意设计边界。scan_network 只解析本机配置中的 listen / URL / proxy 字段并按规范分类(loopback / unspecified / private / external),不能判定时返回 unknown-listener-state info finding;它绝不主动探测或连接远程目标,因此审计本身不会制造真实网络流量,也不会被本机 IDS 误判。
Q: Windows 上能跑吗?会有什么差异?
A: 能跑——plugin 主程序是纯 Node 脚本。但权限类规则(credential-file-permissions / session-root-permissions / session-file-permissions)在 Win32 上没有零副作用 ACL API,所以会返回 skipped(skipReason=platform),不会被当成 pass;报告 coverageVerdict 会判 incomplete。这正是"诚实判定"的设计:宁可标 incomplete 也不假装安全(src/platform/windows.ts:7-16 / src/runner.ts:138-150)。
Q: includeSourceScan 是干什么的,要不要打开?
A: 启用后会额外对每个已安装插件(深度 3、跳过 node_modules/.git)做源码正则扫描,去匹配 eval / new Function / vm / child_process / spawn / fork / Worker / net|http|https|dgram / fetch / WebSocket 等高风险能力字符串。能力命中永远不裁定恶意,只在 finding 里写明"capability present, intended use requires manual confirmation",需要你或团队确认意图。因此更慢、误报更多,README 把它标为可选、默认关闭;建议只在"刚装了一个不熟的插件,想三角验证来源可信度"时按需开启。
Q: 报告 coverageVerdict 显示 incomplete 是坏消息吗?
A: 不一定意味着漏判。它代表有 critical 规则因 skipped(平台不支持或权限不足)或 scanner error 而无法给出结论——Windows 权限规则就是典型触发场景。summarize 会单独统计 skipped / errors 计数,结合 checks 列表看具体规则名与 skipReason,再决定是接受当前覆盖率、提权重跑、还是只把 in-domain 子扫描合并报告。
Q: strict 模式建议开吗?
A: 个人自查保持默认(false),避免 medium finding 单独触发 fail;正式上线前或 CI 卡点场景开 strict,让 medium 等同 high 看待。找到的高优问题建议直接修而不是反复重跑——审计器只诊断、不修,也不替代权限边界与密钥管理规范。
Q: 怎么卸载和降级?
A: 用对应 profile 的 dsh plugin remove security-audit 即可,工具调用入参里没有写全局状态、没有守护进程、没有 $DSH_HOME 之外的副作用;移除后历史只在你自己保存的 JSON 报告里。本身是 v0.0.1,跨版本不保留 schema——升级就直接 dsh plugin add 覆盖。
上手难度
进阶 — 单条命令即可安装并直接调用 report action,但要从 coverageVerdict: incomplete / verdict: fail 的 JSON 里读懂 33 条规则的 code / exposure / recommendation,并据此去修配置或换插件,需要熟悉 DSH 的 ~/.dsh 目录布局与 profile 层栈。
已知问题与限制
- 权限规则在 Windows 一律返回
skipped(src/platform/windows.ts:7-16);coverageVerdict必然incomplete,需在riskVerdict与规则清单维度独立解读 - 报告容量有硬上限:单 action 10s、
report30s;文件 ≤ 200、插件 ≤ 200、会话 ≤ 1,000、findings ≤ 1,000;canonical 输出 ≤ 2 MiB;超限会置truncated:true(src/limits.ts:6-43) - 源码能力扫描深度仅 3 层、单文件 ≤ 1 MiB、累计 ≤ 64 MiB,且只匹配
.ts/.js/.mjs/.cjs/.tsx/.jsx;故意不解析 AST、不混淆解(src/plugins/source-capabilities.ts:20-24, 89-93) - 所有路径操作拒绝 symlink / reparse point;只要你 profile 的 link 字段指向软链,audit 看到的不是"软链"而是"跳出根"的告警(
src/paths.ts:80-95) - zstd 扫描用自家实现的 frame parser 解析 header 与 block header,不展开 block 数据;所以不会触发解压炸弹,但也不会给出"解压后内容是否健康"这层判定(
src/sessions/zstd-scan.ts:1-6, 45-50) scan_network永远不会给出真实监听状态——0.0.0.0配置不代表进程真在监听,配置未声明也不代表没在监听;这是有意边界,已显式标unknown-listener-state- 31+ 处不同 secret 模式里规则
dsh_test_not_a_real_secret_*走 allowlist(src/redact.ts:28-30);其它明显无效的测试 token 也会被当成真 secret 报,自部署时记得把 fixture 里的 token 改成这条 prefix,或写到自己的 allowlist - 管理员注入的
allowedRoots/allowedEndpoints走精确匹配(无 wildcard / 路径 / userinfo),凡带这些元素的条目会被静默视为无效、永不匹配(src/network/classify.ts:84-96)
DSH 本机安全审计插件 —— 防御性、只读的安全审计:配置、凭据存储元数据、已安装插件来源、关键路径权限、会话文件结构与网络暴露面。输出脱敏、可复现、可定位的风险报告。
仓库:https://github.com/omdsh-dev/dsh-security-audit(public)
动机
DSH 本地环境承载 API Key、token、会话内容和插件加载边界,误配置(服务监听公网、凭据文件权限过宽、插件来源不可信、会话文件结构异常)会造成真实风险。现有工具没有这个视角:
plugin-check只做结构/合规检查——不评估凭据暴露面、危险能力和路径逃逸session-health只做健康诊断——不涉及来源可信度与安全风险裁定- 手工排查不可复现——凭据位置、权限、监听端口、插件来源分散在多处,逐项人工检查极易遗漏且无法留档
本插件以只读方式审计本机 DSH 环境并输出风险报告:不自动修复、不连接远程、不执行被审计插件、不把"没读到"当作"安全"。
安全模型(审计器自身的边界)
- 只读:绝不修改/删除任何文件,绝不执行被审计插件的代码,绝不主动连接远程目标
- 秘密脱敏:疑似秘密只返回类型 / 长度 / 进程内随机 HMAC fingerprint / 路径 / 行号,完整值永不出现在 canonical 输出(设计级保证,非截断)
- 路径围栏:所有路径经 lstat → realpath → containment 检查;
root固定为进程启动时解析的$DSH_HOME(或管理员声明的 allowedRoot),模型参数不能扩大读取范围 - 诚实判定:finding / pass /
skipped/error四态;skipped与error不计为 pass(coverage 降为incomplete);capability finding只提示人工确认、不裁定恶意 - 预算:
- 文件 ≤ 200、插件 ≤ 200、会话 ≤ 1,000、findings ≤ 1,000
- 源码单文件 ≤ 1 MiB(累计 ≤ 64 MiB);canonical 输出 ≤ 2 MiB
- 单 action 10s / report 30s(deadline + AbortSignal 全程检查)
- 工具参数会记入会话日志,不要传入敏感数据
工具声明
注册 security_audit 工具(@deepseek-ai/dsh-security-audit,row id security-audit),统一输出 JSON 文本字符串:所有 action 输出 { tool, version, root, platform, ... } 信封,扫描类 action 带 verdict/riskVerdict/coverageVerdict 与 summary。
| action | 作用 | 输出 |
|---|---|---|
scan_config | DSH 配置、profile、env/credentials 元数据(秘密存在性、权限、外部端点) | findings 含 secretKind/secretLength/fingerprint,无明文 |
scan_plugins | 已安装插件来源、路径、patch、危险静态能力、install script、秘密文件 | capability finding 标注人工确认 |
scan_sessions | 会话目录权限、symlink 逃逸、zstd 帧结构(解压炸弹预算内) | 帧级问题定位到文件 |
scan_network | 监听配置、URL 分类、明文 HTTP、代理路由(不主动联网) | 状态为配置级推断(unknown-listener-state 明确标注) |
report | 汇总四类扫描 | riskVerdict + coverageVerdict 双维度 + findings 汇总 |
rules | 规则目录与适用平台 | 规则 code / severity / critical / platforms |
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | string | ✅ | scan_config / scan_plugins / scan_sessions / scan_network / report / rules |
root | string | root 覆盖;必须等于 $DSH_HOME 或管理员声明的 allowedRoot | |
profile | string | 限定单个 profile(^[A-Za-z0-9._-]{1,64}$,不接受路径) | |
strict | boolean | strict 模式:medium finding 也判 fail。默认 false | |
detail | boolean | 详细输出。默认 true;敏感证据始终脱敏 | |
includeSourceScan | boolean | 启用插件静态源码能力扫描(更慢、更多误报)。默认 false |
输出示例
{"tool":"security_audit","version":1,"root":"$DSH_HOME","platform":"win32","strict":false,
"verdict":"fail","riskVerdict":"fail","coverageVerdict":"complete",
"summary":{"critical":0,"high":1,"medium":0,"low":0},
"findings":[{"code":"secret-in-settings","severity":"high","state":"finding",
"evidence":{"path":"$DSH_HOME/.env","line":13,"secretKind":"api-key","secretLength":35,
"fingerprint":"b99e1887d861d7be","redacted":true}}],
"truncated":false}
设计要点
- 脱敏协议:疑似秘密(token/key/private key/密码)在读取后立即以进程内随机密钥做 HMAC fingerprint,原始值只用于指纹计算,不进 canonical 输出;
redacted:true是协议字段而非截断提示 - 路径围栏:所有路径 lstat(拒绝 symlink)→ realpath → containment 三重校验;
root参数不能扩大读取范围(与启动时解析的$DSH_HOME或 allowedRoot 严格相等) - 诚实判定:
skipped(平台不支持/无权限)与error不计为 pass,coverage 降为incomplete;capability finding(源码静态检测到 eval/网络/进程能力)只提示人工确认,不裁定恶意 - 解压炸弹防护:会话 zstd 扫描按帧预算(单帧大小、累计展开比)截断,不整包解压
- 只读保证:无写文件路径、无子进程执行(源码能力扫描只做静态正则,不运行被审计插件)、无网络连接(scan_network 只解析配置与分类 URL,从不探测)
- 可复现输出:无时间戳、无随机路径顺序(稳定排序);超限截断后置
truncated;canonical 输出 ≤ 2 MiB(契约断言)
构建与测试
# 构建(仅需 monorepo 的 tsc)
node <monorepo>/node_modules/typescript/bin/tsc -p tsconfig.json
# 测试(vitest,112 个用例:redact/paths/config/plugins/sessions/network/permissions/report/register)
node <monorepo>/node_modules/vitest/vitest.mjs run tests
npm 0.1.0-rc.8 兼容(已验证)
本插件已迁移到 npm 0.1.0-rc.8 依赖线,并在 @deepseek-ai/[email protected] 的隔离 consumer 中完成全链路验证:
- 类型/运行时:
@deepseek-ai/cordis@^4.0.1+@deepseek-ai/dsh-tools@>=0.0.1-rc.1 <0.2.0+@deepseek-ai/dsh-invariants@>=0.0.1-rc.1 <0.2.0(peer);不再依赖 unscopedcordis - 独立构建:
npm install(devDependencies 自包含 typescript/vitest/@types/node)→npm run typecheck→npm test→npm run build→npm pack - 消费验证:tarball 装入 rc.8 consumer →
dsh --profile compat --dump-config出现本插件 row → 工具真实注册与执行通过 - 启动方式:
npx -p @deepseek-ai/[email protected] dsh web(lib 生产模式;勿install -g全局安装)
安装
DSH 0.1.0-rc.8(npm)下,插件通过 dsh plugin --profile <profile> add <source> 安装,source 支持 GitHub 仓库或 npm pack tarball。
从 GitHub 安装(推荐)
# 交互式(web)profile
dsh plugin --profile web add github:omdsh-dev/dsh-security-audit
# 一次性任务(headless)profile —— dsh run 默认使用 headless
dsh plugin --profile headless add github:omdsh-dev/dsh-security-audit
从 npm pack tarball 安装
npm pack 产物可直接作为 source 安装:
dsh plugin --profile web add dsh-security-audit-*.tgz
包内 dsh.bundle.patch 会在安装后自动把插件加入 profile 的 layer stack(row id:security-audit)。插件缺失的 peer 依赖(@deepseek-ai/cordis、@deepseek-ai/dsh-tools、@deepseek-ai/dsh-invariants)由 profile 的 healed profiles/node_modules 回退安装提供。
⚠️ web 与 headless 是不同 profile:web 安装不会自动覆盖 headless;
dsh run默认使用 headless profile。Windows 路径使用正斜杠(C:/...)。
验证安装
dsh --profile web --dump-config | grep security-audit
运行验证
dsh run "运行 security_audit 的 report 动作,检查本机 DSH 环境安全风险"
旧场景:monorepo / 本地路径安装
monorepo 方式已标注为旧场景(本地 junction/symlink、手动编辑 profile 层、不支持 GitHub/tarball source 的旧快照):
dsh plugin --profile web add "C:/path/to/dsh-security-audit"
许可
MIT
查看使用指南 →
该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。
收录徽章
[](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-security-audit)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。