DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

shamcleren /

shamcleren/dsh-security-scan

Verified

DSH plugin: local Python/Go/JS/TS security scanning with offline reports, optional runtime baseline and evidence-based AI review

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@9bf6325f

代码安全扫描

面向 Python、Go、JavaScript/TypeScript 的 DSH 插件。扫描、Git hook 和 CLI 共用同一套逻辑;可在工作台按任务启用 Agentic AI,复用 DSH 模型进行证据复核。兼容的官方运行时版本以本包 package.json 的 engines.dsh 为准,未修改上游源码。

产品范围与模型 Token

模式 能力 是否需要模型 Token
静态规则 Semgrep 源码候选、Gitleaks 疑似凭据、可选 OSV 已知依赖公告 不需要;OSV 需要网络,但不调用模型
可选运行时基线检查 对已启动服务做只读 HTTP 检查:安全响应头、Cookie 属性、CORS、调试错误页、目录索引和 .git / .env 等敏感文件暴露 不需要;只访问你明确授权的地址
可选 AI 源码审计 沿调用链复核候选,补充授权、租户隔离等业务风险,归档证据 需要 DSH 已配置模型的额度

运行时基线检查不是完整 DAST:不登录、不提交表单、不发送注入或攻击载荷,也不验证漏洞能否被利用;AI 追踪源码仍属于源码审计。基础规则可复现、低成本并适合 CI,AI 用于按需复核;两者都不能证明不存在漏洞。

新建工作台任务默认启用 AI。要避免模型 Token,先取消「启用 Agentic AI」再运行,或直接使用 CLI / Git hook。 从 AI 对话要求扫描时,即使传 agent_review=false,外层聊天本身仍可能消耗 Token;“不调用模型”指规则执行路径。首次准备扫描器需要下载;准备完成后关闭依赖查询即可离线执行本地规则。

安装与首次扫描

新建扫描任务和从 session 调用 dsh_security_scan_start 时,默认同时开启依赖漏洞查询、密钥泄露检测和 Agentic AI。OSV 查询发送包名及版本;AI 使用已配置 DSH 模型处理必要的源码片段。明确要求关闭时,可在任务中取消对应开关,或传 dependencies=false、secrets=false、agent_review=false。已有任务保留之前保存的选择;底层规则工具、独立 CLI 和 Git hooks 仍用于显式的规则检查,不另起 AI 会话。

需要官方 DSH 0.2.1-rc.5。插件只用公开扩展点,不改 DSH 源码,也不依赖其他插件或自定义应用壳。兼容范围以 package.json 的 engines.dsh 为准,其他版本(包括 0.2.2 预发布版)尚未验证。

推荐安装 GitHub Releases 里的发布包。把 <版本> 换成要安装的版本号(如 0.17.0):

dsh plugin --profile web add https://github.com/shamcleren/dsh-security-scan/releases/download/v<版本>/shamcleren-dsh-security-scan-<版本>.tgz

也可以在 DSH 侧边栏的「插件」页点「添加插件」,把同一个地址粘贴到输入框中安装,或者先下载 .tgz、校验 Release 说明里的 SHA-256,再把地址换成本地绝对路径。官方桌面版使用实际的 desktop profile,Web 版用 web。安装后重启 DSH。升级时用新版本地址再执行一次,DSH 会替换已安装的版本。

通过 DeepSeek Harness 插件合集(dhp)管理的安装,用 dhp plugin install security-scan 安装,之后由 dhp update 更新到合集 catalog 中的发布包。

在 DSH 中选择项目并说:

使用 dsh-security-review 扫描当前仓库,复核候选漏洞和业务权限问题,输出 HTML 报告,把证据和修复建议保存到 JSON。

也可以说:

扫描 https://github.com/example/project.git 的 main 分支,生成 HTML 安全报告。

URL 支持 HTTPS / SSH,不允许内嵌密码或 Token。使用本机现有 Git 凭据助手(macOS 包括 Keychain)和 SSH agent,但不允许命令行交互输入;不会借用市场的 OAuth token。远端仓库临时裸克隆,不 checkout、不执行项目脚本、不安装依赖,不更新用户现有工作树。Git 操作最长 120 秒,大仓库或不可达历史会明确失败。

独立安全扫描工作台

安装后重新打开 DSH,点击**侧边栏上方全局面板区的「安全扫描」**直接进入工作台,与其他插件使用相同的导航、选中状态和折叠侧栏图标,不需要从设置入口进入。

  • 扫描任务:新建、编辑和移除任务,配置本地目录或仓库 URL、分支/提交、全量/增量/暂存区、Git 或历史报告基线、扫描方式、依赖/密钥检测开关、DSH 编辑后自动检查。保存任务不会自行扫描;使用“保存并运行”或“立即扫描”启动。
  • 运行记录:查看排队、扫描阶段、完成、覆盖不完整、失败、取消和中断状态。一次执行一个扫描,最多 10 个待完成运行(包含正在执行的);关闭工作台后任务继续执行。任务修改只影响之后启动的运行。最多保留最近 100 次运行;记录总量超过 4 MiB 时提前淘汰较旧的已结束记录,已有 HTML/JSON 文件不会随着记录滚动删除。
  • 历史报告:查找最近的报告,在工作台内预览 HTML,下载 HTML 或 JSON。启用过 AI 的报告会列出实际模型与累计用量(如 24.1M tok · 缓存命中 98%);用量来自原生会话的 token 统计,缓存命中为缓存读取占输入侧 token 的比例。未启用 AI 或模型未返回用量的旧报告不显示这两项。0.2 报告仍可打开;任务运行记录保留当时的报告目录,修改输出目录后仍可查看这些记录关联的旧报告。
  • 历史清理:运行记录中的“删除记录”仅移除已结束的记录,保留任务、报告和原生 DSH 对话;历史报告中的“删除报告”永久删除该报告的 HTML、JSON 及内含证据,并移除运行记录里的对应报告入口。两种操作均需确认,已导出的副本不受影响。排队、执行或收尾中的记录不可删除;被任务配置或活动扫描用作基线的报告,需要先调整基线并等待扫描结束。报告目录包含未知文件或符号链接时拒绝删除。
  • 扫描设置:查看 Semgrep/Gitleaks 自动安装进度和重试,配置报告目录。自定义扫描器路径、编辑工具与旧版全局开关收在高级设置。设置通过官方 Settings 写入 Profile 的 cordis.patch.yml,不需要手工编辑。

每个本地任务都有 Git hooks 按钮。选择提交前或推送前、安装或卸载,检查仓库和推送基线后再确认。保存任务不会悄悄修改仓库,也不会覆盖已有用户 hook 或 hooksPath。Git hooks 执行 Semgrep 规则;任务里的依赖查询、密钥检测和盘点模式不会自动带入 hook。配置这些检查时请使用手动任务或 DSH 编辑后自动任务。

按任务启用“DSH 编辑后自动检查”后,匹配该代码目录的编辑会合并触发该任务;扫描期间发生的编辑会在结束后再检查一次。不需要同时打开旧版全局开关。用户主动取消记录为“已取消”,Host 正常关闭中止的任务记录为“已中断”,再次打开后由用户决定是否重跑,不自动恢复执行。

任务定义和运行记录保存在实际 DSH 数据目录的 security-scan/tasks.json。任务存储使用独占锁,数据目录应放在本机文件系统。启动时仅自动回收当前用户拥有、格式有效且 PID 已明确不存在的残留锁;活进程、权限不足、符号链接和归属不明的锁均保留。回收通过独占恢复锁串行执行;若回收本身异常中断并遗留 .tasks-recovery.lock,需核实归属后人工处理。移除任务保留报告、运行记录和已经安装的 Git hooks。

工作台使用官方 sidebar.panellist 和 main 扩展点;侧栏按钮由 DSH 统一渲染,工作台显示在主区域,保留侧栏和原有对话。“返回 DSH”回到当前对话,报告链接会直接选择安全扫描面板。同一次插件加载期间,切换到其他面板后返回会恢复未保存的任务和设置草稿;草稿只保存在内存,刷新或卸载不保留。工作台内部离开未保存表单时仍先确认。RPC 仅通过官方 Connection 的 loopback 授权通道开放。报告在独立 sandbox iframe 中显示,不能操作外层 DSH 页面。

工作台可执行规则扫描及按任务启用的 AI 复核,也保留 DSH 会话中的 dsh-security-review 入口。没有扫描器时可选择“仅盘点文件”验证任务和报告流程,但这不会执行静态安全规则。

工作台与会话两种启动入口

  • 工作台启动:新建或编辑任务,保存并运行。新任务默认开启“同步到 DSH 会话”;仅规则扫描生成观察会话。启用 AI 时,始终在规则扫描开始前创建独立的原生执行会话,运行记录中可点击“打开会话”。DSH 只在会话开始第一轮后才把它列入侧栏并显示对话,所以执行会话和观察会话创建后都会先完成一轮不调用模型的空轮次,规则阶段即可在侧栏看到并跟踪进度。
  • 会话启动:在已选择工作区的 DSH session 中说“用安全扫描插件后台扫描当前项目,并复核候选漏洞”。dsh_security_scan_start 创建任务并加入相同队列,直接绑定当前会话。规则扫描完成后,AI 审计排在当前轮次之后执行;启动工具返回 runId 后应结束当前回复,不要循环等待。审计工具调用、结果和报告都留在原会话,不改标题、不新建 session,使用原会话当前模型。dsh_security_scan_status 可查询该次运行。两种入口共用规则、审计工具、原生退出条件、校验和报告保存流程。

执行会话记录规则阶段与结果,以及原生 Agent 的模型响应、工具调用、脱敏取证结果和完成报告,不再只有观察通知。会话记录由 DSH 原生持久化管理;JSON 报告只保存审查事实和引用,不复制整份对话。AI 必须有执行会话:对话入口复用原会话,工作台入口新建会话。关闭同步不会改变这种绑定,只关闭可选进度通知或仅规则扫描的观察会话。已有任务明确保存的同步选项保持原值,新任务默认开启。

同步通知本身不额外调用模型。关闭会话界面不取消任务;可在运行记录取消,也可在执行会话中停止正在运行的 Agent。审计结束会卸载本轮临时工具与提示词,原会话可继续普通对话;后续扫描通过工作台或 dsh_security_scan_start 新建一次运行。同一会话不能同时绑定两个活动扫描。取消尚未执行的扫描只移除它自己的待办消息;取消正在执行的审计保留其他待办输入,后续调度遵循 DSH 原生行为。对话启动默认开启依赖漏洞、密钥泄露检测和 AI;用户明确排除的检查按参数关闭。CLI 和兼容的同步 dsh_security_scan_audit 不自动创建会话。

如果结果为“覆盖不完整”,展开运行记录中的“覆盖缺口与诊断”,分别查看源码、密钥、依赖与 AI 的状态。例如文件数量上限、不支持的锁文件版本或来源、模型请求失败或未完成候选复核属于不同原因;缩小到具体子项目后重扫,不通过提高置信度或忽略缺口来标记完成。

按任务启用 Agentic AI

新任务默认打开 启用 Agentic AI;可以编辑任务关闭或切换模型,保存后运行。工作台启动固定使用插件的 安全审计 preset(dsh-security-audit);对话入口保留原会话配置,只在审计轮次临时提供审计工具和提示词。如果当前聊天模式隐藏了扫描启动工具,请新建“安全审计”模式的会话或从工作台启动;已有非空会话的 preset 是否可切换由原生 DSH 决定。它复用官方 Shell(macOS/Linux 为 bash,Windows 为 pwsh)、文件读写、glob/grep 搜索、Skills、后台任务工具,并提供审计工具与官方上下文压缩;基础操作沿用 DSH 宿主沙箱和审批策略,审计默认不修改代码。初版不提供任意 preset 切换。每个任务的代码来源、扫描范围、基线、自动触发和 AI 模型选择分别保存;可搜索或复制已有任务,复制后先编辑再保存,不自动启动。

流程是:代码快照 → 规则与基线 → AI 计划和取证 → 复核结论 → HTML 报告。工作台通过官方 ctx.agents.create() 新建执行会话;对话入口通过已有 Agent 的 followup() 排队,不重建或接管会话生命周期。AI 均由原生 Agent Loop 执行。工作台默认读取 DSH 默认模型,也可在“模型选择”下拉框选择 DSH 已配置的模型,无需手填 Provider 或模型 ID。默认选择“跟随 DSH 默认模型”,可刷新模型列表;旧任务中未被列表列出的模型会保留并提示,不自动替换。插件不保存或要求另一份 API Key。启用表示允许把选取的源码片段发送给该模型,DSH 编辑后自动任务沿用这一选择。

AI 不是单次总结扫描器输出:它可以列出文件、选择审查方向、按需读取精确快照、追踪调用者和安全保护、批量复核候选并补充业务风险。执行轮次、上下文压缩、输出限制和结束由原生 DSH Agent Runtime 管理;不再叠加插件的 12 轮 / 5 分钟 / 4096 Token 限制。dsh_security_scan_review_finish 只记录检查点,不强制结束对话。原生自然结束但仍有未复核候选时,任务显示“已结束”,同时单独标明覆盖缺口。模型失败或取消时保留已有结果,不视为安全通过。

运行记录展示实际模型、轮次、读取文件、已复核候选及操作记录;报告包含同样的审查范围和结构化引用。规则阶段仅生成私有 JSON 检查点;执行结束后发布一份最终 JSON + HTML,再显示报告入口。检查点随本次工作清理,不出现在报告列表中。任务和报告记录操作事实与结论;实际模型与工具对话保存在原生执行 session,取证内容会进入该 session。AI 只复核可取证的源码候选,依赖公告和非源码密钥发现留在规则报告并显示为源码复核范围外;候选按页读取,避免大批依赖结果挤占模型上下文。工具参数、未读引用等拒绝原因会显示在执行记录,并反馈给模型纠正;不因累计工具参数错误强制结束原生对话。

插件通过 Bundle 中的 @deepseek-ai/dsh-agent-preset 声明注册安全审计模式,不更改默认模式。旧 $DSH_HOME/.agent-presets/dsh-security-audit/ 目录保留供追溯,当前运行时不再从该目录加载本插件预设;用户自定义预设需按官方声明式配置迁移。

AI 的审计工具包括计划、文件列表、候选分页、证据读取、复核提交和覆盖检查点,并可调用上述官方基础工具。基础工具读取不能替代已归档的证据引用;审计默认只读,不执行项目脚本或漏洞载荷。审计证据限制在本次快照中的非隐藏 Python/Go/JS/TS 文件;每次最多 5 个文件、每文件 200 行,不再另设累计 100 文件的审查上限,仍受实际快照和原生上下文管理约束。插件不再拼接模型历史,也不再施加旧版 512 KiB 上下文或 256 KiB 响应上限;模型请求与会话历史由原生运行时处理。DSH 当前模型、输出 Token 和执行预算仍然生效,输出上限会单独标明。同一位置和 CWE 的重复补充发现不会重复计数。确认和排除均需引用真实已读的行,修改后的源码会拒绝读取。常见凭据字面量在发送前做脱敏,但这不是识别全部敏感信息的保证;仍应选择适合该代码保密级别的 DSH 模型。

AI 结束只表示本次有界流程结束,不代表所有文件或业务链路均已覆盖,不作为安全认证。AI 不执行复现代码,修复建议需要人工判断和针对性验证。规则未覆盖的候选(例如配置文件中的密钥)可能需要在会话中进一步审查;CLI/Git hooks 保持规则执行,不自动消费模型额度。

短命令

插件自带 dsh-security CLI,安装后位于 profile 的 node_modules/.bin。下面的 dsh-security 指 ~/.dsh/profiles/<profile>/node_modules/.bin/dsh-security;自定义了 DSH_HOME 时换成对应目录,也可以把该目录加入 PATH。用 dhp 管理时,dhp plugin exec security-scan -- <参数> 效果相同。--target 是待审查仓库:

# 全量:当前本地文件,包含未提交和未跟踪文件
dsh-security scan --target /absolute/path/project

# 增量:相对显式指定目标分支的共同祖先;包含本地未提交改动
dsh-security scan --target /absolute/path/project --scope diff --base origin/main

# 暂存区:读取 Git index,不混入未暂存修改
dsh-security scan --target /absolute/path/project --scope staged

# 远端指定分支/提交
dsh-security scan --url https://github.com/example/project.git --ref main

# 全量扫描,使用历史报告作为基线,页面默认只看新增
dsh-security scan --target /absolute/path/project --baseline /path/report.json --view new

# 全量扫描指定提交,并与另一个提交比较
dsh-security scan --target /absolute/path/project --ref HEAD --base HEAD~1

# 自定义输出目录;每次创建新的扫描编号,不覆盖历史
dsh-security scan --target /absolute/path/project --output /absolute/path/reports

未指定 --target 时扫描当前目录。命令运行已安装的发布包,不隐式编译开发源码;首次扫描使用 DSH 数据目录(DSH_HOME,默认 ~/.dsh)下的扫描器缓存。

--scope full|diff|staged 控制范围;--view all|new 只控制页面初始筛选,JSON 始终保留全部发现。--base 使用 Git 重新扫描基线;--baseline 使用以前的 JSON,两者互斥。--scope diff 需要 --base,不猜测目标分支。新增判断要求仓库、规则、引擎配置、扫描覆盖可比较;否则显示“未比较”。位置行号移动不会自动产生新问题;完全相同内容的重命名可识别。重命名同时修改、复杂跨文件关系仍需人工复核。

扫描器与依赖查询

安装后首次启用插件会自动准备 Semgrep CE 1.176.1、Gitleaks 8.24.2 和独立 Python 3.13.7,无需预装 Python、pipx 或扫描器。 CLI 首次扫描也会自动准备;只做盘点且未开启密钥检查时无需下载。扫描任务等待准备完成,失败时可在「安全扫描 → 扫描设置」查看状态并重试。

工具保存在 ~/.dsh/security-scan/toolchains/(跟随 DSH_HOME),与系统环境隔离。重复启动复用已验证版本;不会改 PATH、Homebrew、系统 Python 或用户配置。自动下载需要访问 GitHub Releases 和 PyPI;不上传代码。当前支持 macOS arm64/x64、Linux glibc ≥ 2.34 arm64/x64 的发布资产,真实安装及扫描已在 macOS arm64 验证,其他平台尚未实机验收。

插件包携带安装清单和依赖锁,而不是把所有平台二进制塞入 npm 包。uv 0.8.22、Gitleaks 的官方发布包按内置 SHA-256 校验;uv 使用其内置的 Python 发布校验信息,Semgrep 及依赖只接受锁文件中的 wheel 和 SHA-256,不运行项目安装脚本。失败只清理本次创建的目录,已有版本保留;并发安装有锁保护,不自动删除异常退出遗留的锁。

如需提前准备,运行 dsh-security setup。已有扫描器可在高级设置填写绝对路径,留空恢复插件管理;CLI 仍支持 --semgrep /absolute/path/semgrep 和 --gitleaks /absolute/path/gitleaks 覆盖。自定义工具仍需满足上述验证版本。

Semgrep 只用包内 29 条规则,关闭规则联网、指标和版本检查。不是商业跨文件分析的替代品。

语言 / 框架 覆盖
Python:Flask、Django / DRF、Jinja2、requests / httpx、PyJWT Shell、eval/exec、pickle/YAML 反序列化、关闭 TLS 校验、SQL 拼接(f-string / % / format / +)、模板源码拼接、mark_safe / Markup、debug=True、JWT 不验签、SSRF、路径穿越、开放跳转
JavaScript / TypeScript:Express、Koa、Next.js 路由、React、pg / mysql / knex.raw / Prisma raw Shell、eval / new Function / vm、关闭 TLS 校验、innerHTML / dangerouslySetInnerHTML 等 HTML sink、SQL 拼接、SSRF、开放跳转、路径穿越、反射任意来源的带凭据 CORS
Go:net/http、gorilla/mux、Gin、Echo、database/sql、GORM、html/template sh -c、关闭 TLS 校验、SQL 拼接 / Sprintf、路径穿越、开放跳转、SSRF、template.HTML 等绕过转义

SSRF、路径穿越和开放跳转使用函数内污点追踪:只有请求参数(request.args、req.query、r.URL.Query()、c.Query() 等)到达敏感调用时才报告;固定域名前缀、常量表查找、basename / secure_filename / filepath.IsLocal 等常见防护视为已处理。纯字符串字面量的 shell、eval、HTML 和 SQL 不再报告。规则不跨函数或文件追踪,也不解析常量变量的值;权限、租户隔离等业务风险由 AI 复核补充。规则源码在 scripts/build-rules.mjs,执行后生成 rules/baseline.yml;测试会检查两者一致。

可选密钥检测使用自动准备的 Gitleaks:

dsh-security scan --target /path/project --secrets

它扫描受限文件快照(包括隐藏配置文件),不扫描 Git 历史;只使用扫描器内置规则,不执行项目配置。报告不保存匹配值或原始日志,命中仍需判断真假,不尝试使用凭据。

依赖漏洞查询使用官方 OSV API:

dsh-security scan --target /path/project --dependencies

--dependencies 明确允许向 OSV 发送依赖名称和版本,不发送源码。 解析 npm package-lock v2/v3、pnpm lock v9、Go go.sum、Python requirements 精确版本及 uv.lock schema v1;其他格式、未锁定项、分页、结果超限或查询失败都标明覆盖不足。依赖可达性及合适的修复版本仍需复核,不猜测 CVE 或升级版本。

uv.lock 使用真正的 TOML 解析,覆盖所有 registry 包的精确版本,包括开发依赖及不同环境标记下的多个版本;不推断当前机器实际安装集合。名称按 PyPI 规范归一化、同名同版本只查询一次。本地 editable / virtual / directory 项目不当作 PyPI 发布包查询;Git、URL、归档来源和无精确版本的条目标明覆盖不足,不跟随这些位置、不运行 uv 或项目代码。私有 registry 也按名称/版本向 OSV 查询,不能证明同名包与 PyPI 公告对应,需人工核实。未知 schema 或无效 TOML 保留部分覆盖状态,不回显含凭据的解析原文。暂不提供 TOML 精确行映射,报告明确标注锁文件首行。

源码引擎按所选范围执行;密钥和依赖引擎启用时分析整份受限快照,因此即使依赖文件未改动,也可能发现新公告。报告分别列出各引擎状态。

工作台按钮和源码查看面板跟随 DSH 浅色 / 深色主题;主按钮使用主题配套的前景色,悬停、按下及禁用状态保持可辨识。

dsh_security_scan_review_submit 可以只提交 reviews 或只提交 findings,未提供的列表默认为空;至少有一条结果。不接受 null、错误类型或缺失引用。工具输入声明与实际解析使用相同规则,参数错误会给出中文纠正提示、字段路径及期望类型,不回显参数原文。

中文报告与 HTML 内取证

0.9.0 起,新扫描留存限量脱敏代码片段,写入唯一 JSON 数据源并内嵌到 HTML。点击文件 / 行号直接在报告内查看扫描时的代码、高亮定位、查看原文件摘要,无需 VS Code、Cursor、运行中的 DSH 或联网。每个规则命中留存附近上下文,原生 Agent 的已读片段随最终报告归档;每份报告最多 2 MiB / 5000 个片段,每片段最多 200 行。超限与未收录位置显示缺失,不读取当前代码冒充历史快照。凭据命中文件及密钥文件整段隐藏,其他片段按常见凭据模式脱敏;不要把占位符当作安全结论。分享报告也意味着分享其中留存的代码片段,应按仓库访问范围管理。

报告正文使用中文。原生 Agent 提交的证据、修复建议和验证说明必须包含中文,否则工具反馈纠正;标识符、代码和来源原文保留。未翻译的历史结论不会被伪造为中文复核,页面明确标明缺失,原文可展开追溯。每项列出规则 / 公告编号、文件位置、复核判断与未验证项。

运行时基线检查

在任务的“检查项”里填写服务地址(例如 http://127.0.0.1:3000),勾选“我确认有权对该地址执行只读检查”后保存。CLI 使用 --dynamic URL,对话入口的 dsh_security_scan_start / dsh_security_scan_audit 使用 dynamic_url 参数;显式传入地址即视为授权。留空则完全跳过,不产生任何网络请求。

dsh-security scan --target /path/to/project --dynamic http://127.0.0.1:3000
  • 每次最多发送 12 个同源 GET 请求,单个请求 10 秒超时,响应正文最多读取 256 KiB;同源跳转最多跟随 3 次,跨源跳转不跟随。
  • 地址只接受 http / https,不允许内嵌用户名、密码或片段。报告只保存端点、状态码和结论,不保存响应正文或 Cookie 值。
  • 敏感文件探测先请求一个随机不存在的路径作为对照,单页应用“所有路径都返回首页”的情况不会误报。本机 http 地址不报告明文传输,HTTPS / HSTS / Secure Cookie 需在实际部署环境检查。
  • 服务不可达时,该项标记为失败、报告覆盖不完整,静态扫描结果照常发布,任务不判为失败。
  • 运行时发现在报告中归为“运行时风险”,位置显示为 GET 地址 · HTTP 状态;SARIF 使用端点 URL 作为位置。只有同一地址的上一次完整检查才参与新增 / 未再发现对比,旧报告的静态基线不受影响。

报告阅读与修复

0.8.2 起,报告首页优先展示中文处理清单:复核标记的源码风险、尚待追踪的源码、待核实凭据、需要评估升级的依赖包。依赖公告记录数不当作已证实漏洞数;同类源码风险集中展示全部位置。各引擎覆盖状态单独说明,详细英文原文、公告链接和执行日志按需展开。默认隐藏已排除项,可以在原始发现中切换筛选。

新的 AI 审查要求中文结论。取证工具隐藏了凭据原值时,不接受模型凭该占位符将其排除;保留待复核,并提示核实。旧报告中引用脱敏占位符的排除结论显示复查提示,但不悄悄改写历史 JSON 状态。

  • 先看执行结论、已确认 / 待复核记录数和各引擎覆盖缺口。执行结束不代表不存在漏洞,也不代表 AI 逐文件审查了整个仓库。
  • 结果按源码风险、依赖漏洞、凭据泄漏分组;依赖再按包聚合。仅基于 OSV 明确的 aliases 合并同一漏洞,不把同包的不同公告当作重复。原始记录、文件位置、不同版本和复核状态仍保存在 JSON 中。
  • OSV 查询同时获取公告摘要、别名、修复版本与参考链接。修复版本可能属于不同维护分支,不能直接选“最大版本”就保证修复所有漏洞;升级约束和锁文件后应测试并复扫。详情请求失败不丢弃候选、不猜版本。
  • 在 DSH 或独立 HTML 内点击文件 / 引用,优先查看留存的扫描快照;即使工作区后来改变,也不会替换已归档证据。独立 HTML 在页面内打开已留存的脱敏代码片段,远端提交同样可离线查看已归档片段。旧报告的依赖行号通常为 1,新扫描的 requirements / go.sum 提供精确行号,其他格式明确标识清单首行。
  • 支持包 / 文件 / 公告搜索、风险 / 状态 / 基线 / 类型筛选、展开收起、打印 PDF。打印展开所有详情,仍尊重当前筛选。
  • 任务结束后执行 session 给出结束通知与最终 HTML 链接;失败、取消和覆盖缺口不伪装成通过。

报告与模型复核

默认输出到实际 DSH 数据目录的 security-scan/reports/<扫描编号>/:

report.json  # 唯一数据源:提交/快照、范围、规则、发现、证据、建议、历史比较
report.html  # 从 JSON 生成,可离线查看、筛选、展开和打印为 PDF

不生成 Markdown 报告。长期只需保留 JSON,HTML 可重新生成。HTML 不加载外部脚本、字体或资源;所有报告字段作为文本转义,仅 http/https 引用转换为安全链接;新窗口链接使用 noopener/noreferrer。报告包含仓库元数据和漏洞位置,分享前按项目保密要求处理。

# 列出最近报告(自动检查的报告也在这里)
dsh-security list
dsh-security render --report /path/report.json --output /path/new-report.html
dsh-security render --report /path/report.json --output /path/report.sarif --format sarif

正常扫描统一通过 dsh_security_scan_start 或工作台发起。兼容工具仍可用于单次人工取证:dsh_security_scan_audit 生成报告;dsh_security_scan_read_evidence 读取精确快照中的代码供当前模型复核;dsh_security_scan_review_report 保存确认、排除、补充发现、修复建议和验证方式,生成新的 JSON/HTML 版本,保留原报告。远端证据按记录的提交重新读取;本地工作树或 index 变化后必须重扫。复核不自动修改用户代码。要求修复时,模型可以通过 DSH 原有编辑/测试工具生成补丁和针对性测试,再重新扫描验证。

CLI 本身不启动额外 LLM。CLI 结果标记待复核;模型复核在 DSH 会话或工作台中按任务执行。CI 可导入已有复核 JSON:

dsh-security review --report /path/report.json --reviews /path/reviews.json
dsh-security check --report /path/reviewed-report.json --fail-on high

复核输入是数组,每项包含 findingId、status(confirmed/needs-review/dismissed)、severity、evidence、recommendation、verification、reviewer。未复核部分不会自动算通过;“本次未检出”不会自动算已修复。

可选自动检查

Git hooks

dsh-security hook --target /path/project --event pre-commit
dsh-security hook --target /path/project --event pre-push --base origin/main
dsh-security hook --target /path/project --event pre-commit --action remove

仅在显式安装命令后写入目标仓库的 hook。pre-push 读取 Git 提供的实际推送提交,逐个检查非删除的 ref,不混入未提交改动。默认提醒,不阻断提交。ENFORCE=1 可令扫描失败/不完整阻断 hook;候选发现不会冒充已确认漏洞来阻断。复核后可用 ACTION=check FAIL_ON=high|medium 对新增、已确认问题执行质量门禁。

已有 hook 或 core.hooksPath 一律保留;请将上述 scan 命令接入既有 hook 管理器,不自动覆盖或拼接未知脚本。修改本插件的 hook 选项时先 remove 再 install。钩子固定引用安装时的 CLI、Node、扫描器和报告目录,移动安装后应重新安装 hook。

DSH 编辑后检查

在 DSH 插件配置页修改,或在 ~/.dsh/profiles/web/cordis.patch.yml 中设置,默认关闭:

- id: security-scan
  config:
    semgrepPath: /absolute/path/to/semgrep
    gitleaksPath: /absolute/path/to/gitleaks
    autoScan: true
    hookTools: [write, edit, str_replace_editor, write_file, edit_file, apply_patch]

使用官方 tools/result 事件观察成功的指定工具调用;按工作区合并连续编辑,后台对 HEAD 做增量规则检查。默认覆盖官方 write、edit 和 str_replace_editor,并保留其他编辑插件常用别名;str_replace_editor 的 view 不触发。旧版显式配置了别名列表的用户,可在工作台扫描设置里补入官方名称。不监听本插件自己的工具,不递归扫描报告,不自动联网查询或启动 LLM;报告位置写入 Host 日志。无 Git 历史或扫描失败会提示重新手动检查。禁用后停止接收新任务;卸载时取消并等待已有任务。

CI / 定期全量

统一入口也可在已准备好 DSH、插件和扫描器的 CI runner 中调用:

# PR/MR job:TARGET_BRANCH 由 CI 提供,先确保目标分支历史已获取
dsh-security scan --target "$PROJECT_DIR" --scope diff --base "$TARGET_BRANCH" --output "$ARTIFACT_DIR/security"
# 主分支或定期 job
dsh-security scan --target "$PROJECT_DIR" --scope full --output "$ARTIFACT_DIR/security"

归档 JSON/HTML;如平台支持,再导出 SARIF。调度由现有 CI 配置负责,此插件不创建系统 cron、不修改远端流水线。没有后台模型账号时,CI 只运行规则,不能将其称作已完成模型审计。

退出码:0 扫描完成且未触发所配置门禁;1 新增已确认问题超过阈值;2 扫描不完整、扫描器缺失/失败或输入错误。--engine inventory 只盘点范围,不代表安全检查通过。

边界与开发

临时快照限 5000 个文本文件、20000 个目录项、单文件 1 MiB、总计 64 MiB;源码分批执行,每批最多 250 个文件,遍历整份支持语言快照;不再在 1500 文件处截断。规范化报告最多保留 2000 条发现,超限明确记录。AI 暂不读取隐藏源码;二进制、符号链接、依赖/构建目录按报告说明排除。本地 Git 工作区使用 git ls-files --cached --others --exclude-standard,默认遵循嵌套 .gitignore、反向规则和 Git 标准排除规则;已跟踪文件即使匹配忽略项仍扫描。普通非 Git 目录只应用内置排除目录。提交和暂存区扫描以 Git 中记录的文件为准。不应用 .semgrepignore 或项目自带扫描配置;不执行子模块、项目脚本或依赖安装。超限和覆盖缺口在报告中保留。

在本仓库根目录执行(Node.js 22.19+ 或 24+,pnpm 版本见 packageManager):

pnpm install --frozen-lockfile --ignore-scripts
pnpm typecheck
pnpm test
SECURITY_TEST_SEMGREP=/path/semgrep pnpm test
pnpm build

lib/ 是当前发布版本的构建产物,提交在仓库里供 Git 方式安装使用;日常修改只需让检查通过,发布时由维护者重新构建。

规则引擎真实用例未配置扫描器时明确跳过。设置 SECURITY_TEST_INSTALLATION 指向隔离的测试安装后,还会验证发布包经官方 profile 加载器成功合成;未设置时该项明确跳过。真实微信/模型账号、远端私有仓库权限和不同平台兼容性需要分别验收。

安全审计的基础工具与后台审计会话保持一致;基础 read/bash 可以辅助定位,最终报告引用仍需通过 dsh_security_scan_review_read 校验扫描版本并保留脱敏片段。当前版本使用 Bundle 声明式预设;旧目录保留,升级插件并重启 DSH 后加载新工具实现。

工具校验反馈

dsh_security_scan_review_submit 会校验整批证据,再保存结论。工具返回 unread-citation 表示引用范围尚未通过 dsh_security_scan_review_read 完整读取;redacted-secret 表示不能把被隐藏的密钥直接认定为误报。这类拒绝允许模型修正后继续,不等于扫描失败。反馈用中文说明,issues 定位记录 ID、数组下标和文件行范围;saved=false 表示本批没有保存,修正后可整批或分批重交。单次最多列出 20 个问题,其余数量在 omittedIssues 中展示。取证结果的 redactedLines 明确标记隐藏行;没有原值依据时应保留待复核。

结果处理与复扫

工作台提供任务概览、运行状态筛选和搜索。任务的低频操作收进“更多操作”;AI 模型配置按需展开。离开未保存的任务或设置时会提示保留编辑,扫描提交期间禁止重复提交;连接中断保留已有内容并自动重连。

打开报告后,在“接下来,处理扫描结果”中按源码风险、依赖漏洞、凭据泄漏类型,以及风险级别、复核状态和搜索组合筛选。可逐条多选、全选当前结果、取消当前结果或清空全部选择;切换筛选保留已选项,并显示筛选外已选数量。每次最多选择 20 个已确认或待复核问题;超过剩余名额时按钮明确显示仅选取当前结果前 N 项。已排除问题不进入选择列表。选择完成后,默认点击“在会话中修复”,通过对话决定最终交付;也可明确选择“本地修改”。任务记住该偏好。

默认模式先在独立本地分支和 worktree 中核实问题、修复并验证,再向用户展示差异、测试和交付方案。平台工具、登录和权限允许时优先建议草稿 PR;没有远端、工具或权限时,仍可完成本地分支修复,保留差异和工作区,由用户决定下一步。点击修复按钮不自动授权提交、推送或创建 PR,交付动作在对话中取得用户决定;不强推、不自动合并或部署。

工作台展示可安全读取的 origin 推送仓库、当前分支和起点提交。远端缺失、地址含凭据或平台不同不会阻止建立本地修复分支,也不会暴露原始凭据地址。独立分支仍要求本地 Git 历史、明确分支及干净工作区;否则需先处理已有改动或显式选择本地修改,不擅自暂存、提交或覆盖用户内容。发起时再次校验预览对应的起点。工作区保留在任务存储目录的 repair-worktrees/,分支名为 security/repair-…,不切换原工作区。

PR 创建通过会话中实际可用且已授权的平台工具完成,插件不新增平台凭据、不借用市场令牌、不猜测 API。用户同意且创建成功后,会话可调用 dsh_security_scan_record_repair_delivery 回填链接,工作台“刷新交付状态”后可打开“查看 PR 差异”。回填工具只接受关联会话及记录仓库的 PR 链接,不独立查询或认证远端 PR 状态。未记录远端时,PR 链接仍可在会话中交付。

本地模式在扫描目录直接修改,要求保留已有改动,不自动提交、推送或创建 PR。两种模式都只处理选中项,先核实当前源码并说明验证结果;沿用默认模型、会话配置和原生工具权限。每份报告仍关联一个修复会话,重试复用请求身份、分支和工作区;已发起后不更换选中项或交付模式。旧版已存在的修复记录继续按本地模式处理。修复工作区不会因关闭插件、删除报告或完成会话而自动删除,避免丢失未提交或未推送内容。

标记误报并在后续扫描中隐藏

在“接下来,处理扫描结果”中选中问题,点击“标记为误报”并填写原因(必填,最多 500 字)。之后的扫描在同一仓库、同一引擎、同一规则、同一文件且代码指纹一致时,自动将其标为“已排除”并默认隐藏:不计入失败阈值和 CLI 退出码,不进入 SARIF,也不交给 AI 复核。行号移动不影响匹配;命中代码被修改、文件改名或换了仓库时会重新显示,避免一次排除掩盖后来引入的风险。报告保留记录并注明你在哪天、以什么原因排除,在筛选中选“全部”即可查看。排除后当前报告的可处理列表立即更新,不必重新扫描。

排除记录只保存在本机 security-scan/suppressions.json(与报告目录同级),不写入被扫描的仓库,最多 5000 条。在「扫描设置 → 已排除的问题」中可以搜索并“恢复”,恢复后下一次扫描重新显示。AI 补充的发现没有跨运行的稳定指纹,不能排除;已排除的问题也不能再提交复核结论。文件为符号链接、格式损坏或正被其他进程写入时,扫描照常完成并在报告中说明排除记录未生效,不会覆盖该文件。

CLI 和 Git hook 默认使用同一份列表:

dsh-security suppress --action list
dsh-security suppress --action add --report /path/report.json --finding ID1,ID2 --reason "参数来自内部常量"
dsh-security suppress --action remove --id SUPPRESSION_ID
# 指定其他列表,或本次扫描忽略排除记录
dsh-security scan --target /path/project --suppressions /path/suppressions.json
dsh-security scan --target /path/project --ignore-suppressions

只有关联了运行记录的本地工作区报告提供修复入口;远端仓库、固定 ref 和暂存区报告需先在本地工作区扫描。

修复会话按五步闭环执行:逐项核实、最小修复、回归验证、复扫确认、总结。提示中附带按类别整理的修复要点(命令注入、SQL 注入、XSS、动态执行、反序列化、TLS 校验、路径穿越、SSRF、开放跳转、模板注入、调试模式、JWT、CORS、依赖升级、凭据处理、运行时配置)。修复和测试完成后,会话调用 dsh_security_scan_repair_rescan,按原配置排队一次复扫;重复调用不会排第二次,扫描结束后对比结果会回到同一会话。复扫报告的“接下来”面板显示 选择问题 → 会话修复 → 复扫验证 → 对比结果 的当前进度;仍然存在或新增的问题可以点击“继续修复剩余问题 · 第 N 轮”发回同一会话,只包含原选中问题(按稳定指纹匹配)和新增问题,每轮最多 20 项。没有剩余问题时会明确提示。

也可以回到原报告手动点击“按原配置复扫”。本地模式复扫使用历史运行保存的完整任务配置,包括原目标、scope、ref、Git/报告基线及模型策略;默认会话模式通过“复扫修复分支”扫描已记录的独立工作区,保留原 scope、基线及模型策略,并关联已回填的 PR 链接。工作区丢失或分支变更会拒绝复扫;编辑或删除任务定义不会改变复扫配置。工具路径与报告保存目录使用当前设置。扫描运行记录标记为“复扫”,完成后可查看两份报告的对比;原报告不被修改。

对比按规则来源、文件与稳定指纹匹配,区分“仍然存在”“新增”“本次未再发现”和“待验证”。只有仓库、范围、规则摘要、扫描器版本及覆盖情况可比时才确认增减;AI 补充发现没有跨运行稳定身份,始终保留待验证。“本次未再发现”不等于已修复。 覆盖不足或扫描失败不会把旧问题判为已修复。规则命中与人工/AI 复核状态分别展示。

运行中的复扫会保护原报告,防止删除;结束后可以显式删除原报告,这会同时移除该项对比关联。修复会话由 DSH Host 管理,关闭工作台不会取消会话。要停止修复请在原生会话中取消。运行记录依旧遵守 100 条保留上限,删除记录会失去该报告的后续动作配置;独立导出的 HTML 保持离线只读。

UI 回归使用隔离示例,不读取真实仓库或调用模型:在组件目录执行 pnpm test:ui,需要 Playwright 和 Chromium。可通过 PLAYWRIGHT_MODULE 指定 Playwright 模块入口,CHROMIUM_EXECUTABLE 指定测试浏览器,UI_SCREENSHOT 指定截图路径。脚本会校验草稿保护、键盘焦点、重复提交、重连、修复选择、快捷选择、运行时检查授权、继续修复、复扫、筛选、标记误报与恢复和窄屏布局。

0.15 工具命名迁移

全局工具统一使用 dsh_security_scan_ 前缀,Skill 为 dsh-security-review;不注册通用旧名别名,避免依赖加载顺序抢占其他插件。Profile 配置 ID security-scan、审计 preset dsh-security-audit、CLI dsh-security 和已有任务/报告格式保持兼容。

0.14 及更早的入口 0.15 入口
security_start_scan dsh_security_scan_start
security_scan_status dsh_security_scan_status
security_scan dsh_security_scan_rules
security_audit dsh_security_scan_audit
security_reports dsh_security_scan_reports
security_read_evidence dsh_security_scan_read_evidence
security_review_report dsh_security_scan_review_report
security_record_repair_delivery dsh_security_scan_record_repair_delivery
Skill security-review Skill dsh-security-review

临时审计工具也使用同一前缀:dsh_security_scan_review_plan/files/candidates/read/submit/finish(斜线表示各个名称的尾部,不是可调用名称)。升级后重启 DSH,再启动新扫描;已保存的自定义提示词、工具白名单和外部工作流应替换旧名。不要依靠旧对话中的历史工具名重新调用。共存测试覆盖另一插件保留 security_audit、security_scan、security-review 且双方先后加载/卸载的情形;这不等同所有第三方插件版本的完整集成验收。

可复现效果评测

见 评测说明 和随包发布的 完整基线。97 个原创合成样例涵盖四种语言和上述框架:46 个带风险样例、51 个安全样例;包含每条规则的漏洞/修复对、常量/净化/白名单等难例,以及规则未覆盖的授权、越权和跨函数 SSRF。固定 Semgrep CE 1.176.1 三次真实运行得到:TP 41、FN 5、FP 2、TN 49;候选精确率 95.3%、召回率 89.1%、F1 92.1%。新样例是与新规则同时编写的,指标天然偏乐观;原有 42 个样例在新规则下为 TP 19、FN 1、FP 0、TN 22。这是一套小型公开合成集上的候选指标,不能作为真实项目漏洞检出率,也未测量 AI 复核效果。

dsh-security evaluate --runs 3 --output /tmp/security-evaluation-new.json
# 使用同一语料的上一份结果阻止新增漏报或误报
# --baseline 指向随包 evaluation/baseline.json 或已归档的同语料结果

CLI 也提供 dsh-security evaluate --semgrep /path/semgrep --baseline /path/baseline.json --output /tmp/new-result.json。输出保留逐例结果、语言/CWE 分组、规则与语料摘要、运行环境和耗时样本;相同语料新增漏报或误报退出 1,版本/覆盖/输入错误退出 2。没有基线时只测量,不把现有漏报/误报当作安全通过。测试和评测从不执行样例代码、目标应用或载荷,不调用模型或 OSV。

开源使用见 English README、贡献指南、安全反馈 和 第三方说明。许可为 MIT;下载的扫描器和运行时依赖各自遵循其上游许可。

—/ 5

No ratings yet

Verified DSH bundle

Commit 9bf6325f6b3e

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout