dsh-credential-scan
v0.1.0
Published
Credential scanning for DeepSeek Harness: detect AWS keys, GitHub tokens, private keys, JWTs, Slack/Stripe/Google/SendGrid/Discord tokens and generic API keys in text or recursively in a directory tree; entropy-based checks. Output is always masked — neve
Downloads
29
Maintainers
Readme
dsh-credential-scan
DeepSeek Harness 的密钥泄漏扫描工具箱:scan_secrets 在一段文本或文件里检测 AWS 密钥、GitHub 令牌、私钥、JWT、各类平台令牌与通用 API 密钥,entropy_check 用香农熵挑出疑似随机密钥的高熵片段,scan_path 递归扫描整个目录树并按文件汇总。核心约束:输出一律脱敏——只显示密钥首尾各 4 个字符并标注长度,绝不输出完整密钥。只读、零运行时依赖。
- 源码:https://github.com/geeklei/dsh-plugins/tree/main/dsh-credential-scan
- npm:https://www.npmjs.com/package/dsh-credential-scan
功能说明
密钥泄漏是研发流程里最隐蔽也最危险的一类事故:一个 git add . 把 .env 或测试常量里的真实 token 提交上去,几分钟内就可能被自动化爬虫抓走、被公网扫描器利用。事后要追「到底哪些 token 泄露了」非常麻烦——因为普通人眼扫几十个文件根本看不出哪个字符串是密钥。
本插件做两件事,把「找密钥」从碰运气变成可重复的检查:
- 规则识别:内置 12 类密钥的启发式正则,按平台特征(前缀、长度、结构)匹配。规则覆盖 AWS、GitHub、私钥头、JWT、Slack、Stripe、Google、SendGrid、Discord,以及形如
key = 长串的通用 API 密钥。 - 熵识别:随机生成的密钥往往有很高的信息熵。
entropy_check计算整体香农熵并挑出高熵片段,作为规则库之外的兜底,能覆盖没写进规则的新平台 token。
使用上分三种粒度:看一段文本用 scan_secrets,看整棵目录用 scan_path,想做「无规则」的高熵筛选用 entropy_check。三个工具都只读、不联网、不写文件,命中值一律脱敏。
安装
npm install dsh-credential-scan安装后在 cordis.patch.yml 中加入:
- insert:
- id: credential-scan
name: "dsh-credential-scan"使用说明
scan_secrets
在一段文本或单个文件里检测各类密钥。text 传正文或 path 传文件(二选一)。
检测规则:12 类;来源:(内联文本);扫描 4 行
命中 4 处
1. [aws_key_id] 第 1 行 AWS 访问密钥 ID AKIA…MPLE(长度 20)
2. [github_token] 第 2 行 GitHub 个人访问令牌 ghp_…MNOP(长度 46)
3. [private_key] 第 4 行 私钥 ----…----(长度 35)
4. [generic] 第 3 行 通用 API 密钥 S3cR…7890(长度 21)(熵 4.20)
说明:以上值已脱敏,未输出完整密钥。参数:text / path 二选一;max_hits(默认 200,上限 1000);max_chars / max_size。
用户:这段配置里有没有 token,帮我扫一下
助手:调用
scan_secrets,text传配置内容,返回脱敏命中清单
用户:检查 .env 文件是不是混进了真实密钥
助手:调用
scan_secrets,path=.env(注意 .env 常是隐藏文件,scan_path 默认跳过,单文件不受影响)
entropy_check
计算整体香农熵,并列出超过阈值(默认 4.5)且长度达标(默认 ≥8)的高熵片段。适合在没有明确规则时兜底抓「看起来随机」的串。
来源:(内联文本);输入长度 47;整体香农熵 5.26
高熵片段(≥4.5,长度≥8):1 个
1. [偏移 6] AbCd…6789(长度 36)(熵 5.17,长度 36)
提示:熵高不等于就是密钥,需结合上下文判断;片段已脱敏。参数:text / path;min_len(默认 8,范围 4~64);threshold(默认 4.5)。
用户:这段内容里有没有可能是随机密钥的高熵串
助手:调用
entropy_check,text传内容,看哪些片段熵高于阈值
scan_path
递归扫描目录(或单个文件),用同一套规则检测所有文本文件并按文件汇总。跳过二进制与超大文件,可用 exclude 排除 node_modules、dist 等路径。
扫描路径:./src;文件 42 个(跳过二进制 3 个、超大 1 个)
命中文件:src/config.js(2 处)
1. [github_token] 第 12 行 ghp_…MNOP(长度 46)
2. [generic] 第 15 行 S3cR…7890(长度 21)(熵 4.20)
共 1 个文件存在命中;以上值已脱敏。参数:path(目录或文件,必填);exclude(排除路径子串,逗号分隔);max_files(默认 500,上限 10000);max_size / max_hits / max_chars。
用户:在提交前扫一下整个仓库有没有混进密钥,跳过 node_modules
助手:调用
scan_path,path=仓库根、exclude=node_modules,dist,.git
典型场景
- 提交前检查:CI 里或本地推送前
scan_path扫一遍,避免密钥随 commit 入库。 - 历史泄露排查:拉出疑似含密钥的历史文件,
scan_secrets逐段确认,输出脱敏便于分享。 - 配置审查:检查
.env、配置模板、示例常量是否放入了真实 token 而非占位符。 - 文档脱敏复查:写完含示例 token 的文档后,确认展示的是
xxxx…而非真实值。 - 未知平台兜底:新接入的服务 token 不在规则库时,用
entropy_check挑高熵串人工复核。 - PR 扫描:审查 PR 变更内容,重点看新增的常量、配置、脚本是否混入密钥。
- 安全交接:离职 / 交接时确认代码与文档里没有残存凭据。
安全边界
- 输出脱敏(核心约束):所有命中一律经
mask输出——只显示首尾各 4 个字符并标注长度,短串全打码;绝不输出完整密钥。通用密钥还会附带熵值供判断。 - 只读:三个工具都不写入、不修改、不删除文件;测试含源文件 size/mtime 不变的只读性断言。
- 不访问网络:扫描与熵计算全部在本地完成,不做任何外部请求,也不会上传、外发被检出的内容。
- 不执行内容:只是字符串匹配与统计,不对文本做
eval、不解析代码语义。 - 二进制与超大文件:
scan_path跳过 NUL 字节二进制文件与超过max_size的超大文件,避免误报与资源占用。 - 非权威结论:规则与熵都是启发式——可能有漏报(新平台 token 不认识)与误报(低熵的普通长串被当成通用密钥)。工具只负责「标出疑似」,是否真是密钥、是否已泄露,需要人工结合上下文确认。
- 不在输出中回显原文:除脱敏片段外,
scan_secrets/entropy_check不把完整输入回显,避免二次泄露。 - 不自动处理泄露:工具只做检测,不主动删除、替换或上报密钥(涉及破坏性 / 外发操作需由你明确执行)。
其他插件集成说明
| 协作插件 | 集成方式 |
|---|---|
| dsh-dotenv-toolkit | 用 dotenv-toolkit 解析 .env 后,把值交给本插件扫描,区分真实密钥与占位符 |
| dsh-hash-checksum | 对疑似密钥算哈希留证,便于事后比对是否已泄露、是否同一份 |
| dsh-credential-scan 自身 | scan_path 扫全目录 → scan_secrets 逐条确认 → entropy_check 兜底未知类型 |
| dsh-file-search | 先按扩展名 / 关键词定位疑似含密钥的文件,再交给本插件确认 |
| dsh-git-tools | 拉取提交变更,对 diff 文本跑 scan_secrets,实现提交前密钥门禁 |
| dsh-csv-inspect | 扫描导出数据 / 日志 CSV 中是否含 token 列 |
版本说明
- 0.1.0(2026-10-06):初始版本。
scan_secrets:12 类规则(AWS 访问/秘密密钥、GitHub 令牌、私钥头、JWT、Slack、Stripe、Google、SendGrid、Discord、通用 API 密钥),输出脱敏entropy_check:整体香农熵 + 高熵片段列表,可调阈值与最短长度scan_path:递归目录扫描、按文件汇总、跳过二进制与超大文件、可排除路径- 核心安全约束:所有命中值一律
mask脱敏,绝不输出完整密钥
RoadMap
v0.2(计划)
- 增加
url/email/aws arn等上下文字段,命中报告附带语境以便人工判断 - 规则库外置为可扩展 JSON(支持
--rules自定义正则),方便团队加私有平台规则 scan_path增加并发扫描(限制线程数),提升大仓库速度
v0.3(展望)
- 集成
gitleaks风格白名单:对已知非敏感的同款长串(示例、占位符、测试夹具)做豁免 - 增加「相似泄露」检测:同一密钥的哈希出现在多处文件时给出去重报告
- 与 CI 插件联动:
scan_path返回非零退出码即拒绝 push / PR merge
FAQ
Q:为什么输出里看不到完整密钥,只有 XXXX…YYYY?
这是刻意设计的安全约束。密钥一旦被打印,就可能进入聊天记录、日志、截图而二次泄露。mask 只保留首尾各 4 个字符用于人工辨识,必要时你再自行核对原文。
Q:通用密钥这条会不会误报很多?
会。generic 规则按「key / token / secret / password 等词 + 赋值 + ≥8 位长串」匹配,可能把 apiKey = "development-dummy-value" 之类也标出来。所以通用命中会额外给出熵值,熵低的基本是占位符,可自行忽略;也可以用 validate_template / 代码评审二次确认。
Q:为什么 scan_path 默认跳过 .env?
它默认跳过隐藏项(以 . 开头)是为了避免扫进 .git、.cache 等系统目录。需要扫 .env 这类隐藏文件时,用 scan_secrets 的 path 参数直接指定单文件即可,不受跳过隐藏项影响。
Q:某平台的 token 不在规则库里怎么办?
先用 entropy_check 兜底——随机 token 通常熵 ≥4.5,能把它挑出来。确定后可在 RoadMap 的 v0.2 里给它加一条自定义正则,或提交 issue 让我们扩充规则库。
Q:熵高就一定是密钥吗? 不是。高熵只说明「随机性 / 复杂度高」,一段压缩数据、一个 GUID、一串拼音缩写也可能熵高。请结合所在位置(配置、环境变量、凭据字段)与上下文判断,工具只负责缩小范围。
Q:扫出来命中了,工具会帮我删除或替换吗?
不会。dsh-credential-scan 只做检测和脱敏展示,绝不自动修改文件,也不会上报或外发。涉及删除 / 轮换 / 上报的操作应严格由你自己决定并执行。
Q:文件很大会不会卡住?
scan_path 跳过超过 max_size(默认 10240 KB)的文件,并用 max_files(默认 500)限制文件数,避免扫描海量文件拖慢。需要扫更大的文件时再调高上限。
Q:二进制文件会被扫描吗? 不会。二进制内容里 NUL 字节会被识别并跳过,既避免误报,也避免把无关的字节序列当成密钥。
源码与发布地址
- 源码:https://github.com/geeklei/dsh-plugins/tree/main/dsh-credential-scan
- npm:https://www.npmjs.com/package/dsh-credential-scan
许可证
MIT
