- 应用安全
- 供应链安全
【免费下载链接】gitleaks
Find secrets with Gitleaks 🔑
Gitleaks 是一款用于扫描仓库中硬编码密钥的开源工具,其默认检测能力全部来自自动生成的 config/gitleaks.toml 配置文件。本篇指南基于仓库根目录的 CONTRIBUTING.md,完整讲解如何为 Gitleaks 贡献一条新的检测规则:从创建规则源码文件、注册到生成入口、再到运行make config/gitleaks.toml产出正式配置并提交 Pull Request。读完本文,你将掌握 Gitleaks 规则体系的两大核心生成函数(GenerateSemiGenericRegex与GenerateUniqueTokenRegex)、真/假阳性验证机制,以及一条规则从 Go 源码到 TOML 配置的完整生命周期。
一、贡献流程总览:Issues 与 Pull Requests
Issues:先声明再动手
如果你希望贡献一个新功能或 Bug 修复,先检查仓库中是否已有描述该提议的 open issue:
- 若已有对应 issue,在 issue 下留言声明你正在处理它,避免多人重复劳动;
- 若没有,则新建一个 issue 详细描述你的改动,并在后续的 PR 中链接到该 issue。
Pull Requests:模板与测试
提交 PR 时尽量完整填写 PR 模板,并确保所有测试通过。仓库的 Makefile 中定义了test目标(go test -v ./... --race),且test依赖config/gitleaks.toml——这意味着任何规则改动都会先触发配置重新生成,再执行全量测试。此外,如果你看到他人提交的 PR 并希望其进入下一个版本,可以在该 PR 描述上点一个 👍(thumbs up)表示支持。
二、规则代码生成架构:为什么新增规则要改 Go 代码
Gitleaks 的默认配置并非手写 TOML,而是通过cmd/generate下的一组 Go 程序自动生成。整个生成链路为:
- 每条规则以 Go 函数形式定义在 cmd/generate/config/rules 目录下的独立文件中(每个 provider 一个文件,例如
beamer.go、aws.go、github.go); - cmd/generate/config/main.go 的
main()把所有这些规则函数收集进configRulesslice; - 程序通过 cmd/generate/config/rules/config.tmpl 这个 Go
text/template模板,把规则对象渲染成 TOML,写入 config/gitleaks.toml; - Makefile 中
config/gitleaks.toml目标的依赖是$(wildcard cmd/generate/config/**/*),执行体为go generate ./...,因此改动cmd/generate下任何文件后运行make config/gitleaks.toml即可触发重新生成。
模板文件开头特意注明:This file has been auto-generated. Do not edit manually.——也就是说,正确的贡献方式是改 Go 源码,而不是直接手改 TOML。每条规则在模板中会被渲染为一段[[rules]]配置块,包含id、description、regex、keywords,并可选渲染path、secretGroup、entropy、tags与规则级 allowlist。
三、第一步:创建cmd/generate/config/rules/{provider}.go
新增规则的第一步是创建cmd/generate/config/rules/{provider}.go文件。以 cmd/generate/config/rules/beamer.go 为例(该文件与文档示例完全一致),一条规则函数的完整形态如下:
package rules import ( "github.com/zricethezav/gitleaks/v8/cmd/generate/config/utils" "github.com/zricethezav/gitleaks/v8/cmd/generate/secrets" "github.com/zricethezav/gitleaks/v8/config" ) func Beamer() *config.Rule { // define rule r := config.Rule{ Description: "Detected a Beamer API token, potentially compromising content management and exposing sensitive notifications and updates.", RuleID: "beamer-api-token", Regex: utils.GenerateSemiGenericRegex([]string{"beamer"}, `b_[a-z0-9=_\-]{44}`, true), Keywords: []string{"beamer"}, } // validate tps := utils.GenerateSampleSecrets("beamer", "b_"+secrets.NewSecret(utils.AlphaNumericExtended("44"))) fps := []string{ `│ ├── R21A-A-V010SP13RC181024R16900-CN-B_250K-Release-OTA-97B6C6C59241976086FABDC41472150C.bfu`, } return utils.Validate(r, tps, fps) }对照 config/rule.go 中Rule结构体的定义,可以理解各字段的语义:
- Description:人类可读的规则描述,会原样写入 TOML,也会出现在扫描报告中;
- RuleID:规则唯一标识,
main.go会对它做唯一性检查,重复会直接 Fatal; - Regex:用于检测秘密的 Go 正则表达式,是整个规则的核心;
- Keywords:预过滤关键词。Gitleaks 在跑完整正则前会先做一次快速的字符串比较,只有内容中出现至少一个 keyword 才继续匹配正则,相当于扫描性能的"前置过滤器"。从 config/rule.go 的注释可见,keywords 用于 pre-regex check filtering;
- 此外
Rule还支持Entropy(香农熵下限)、SecretGroup(从正则匹配中提取秘密的捕获组序号)、Path(按文件路径过滤)、Tags(报告元数据)、Allowlists(规则级豁免)等字段,需要时可在规则文件中补充。
正则与秘密生成:两条核心辅助函数
为了让规则风格统一、便于维护,绝大多数规则都应使用 cmd/generate/config/utils/generate.go 中定义的两个生成器。其函数签名如下:
func GenerateSemiGenericRegex(identifiers []string, secretRegex string, isCaseInsensitive bool) *regexp.Regexp func GenerateUniqueTokenRegex(secretRegex string, isCaseInsensitive bool) *regexp.RegexpGenerateSemiGenericRegex(半通用正则)接受一组标识符(identifiers)、一个秘密正则、以及是否大小写不敏感的布尔值。identifiers列表应当与规则定义中的Keywords保持一致——两者都充当过滤器,告诉 Gitleaks "内容中至少出现这些字符串之一,才可能构成泄露"。从源码可以看到它实际拼装的完整模式:
(?i)[\w.-]{0,50}?(?:ident1|ident2)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(SECRET)(?:[\x60'"\s;]|\\[nr]|$)其中运算符部分覆盖了常见的赋值或函数调用写法:=、>、:、:=、::=、||、=>、?=、,等;秘密前后的边界符则保证了匹配到的是真实值而不是长文本中的偶然命中。
GenerateUniqueTokenRegex(唯一令牌正则)只接受秘密正则与大小写不敏感开关。当令牌本身足够独特、无需标识符辅助时使用。文档给出了选型建议:如果令牌前缀超过 3 个字符,通常就可以直接用GenerateUniqueTokenRegex。仓库中的对照示例是 cmd/generate/config/rules/pulumi.go——Pulumi 的 API Token 前缀为pul-,足够独特,因此直接使用GenerateUniqueTokenRegex("pul-[a-f0-9]{40}", false),并辅以Entropy: 2与Keywords: []string{"pul-"};而 Beamer 的b_前缀只有 2 个字符、不够独特,所以改用GenerateSemiGenericRegex并要求beamer标识符必须出现。
此外 patterns.go 还提供了一批字符类辅助函数,用于拼接秘密正则的字符集部分:
| 函数 | 生成的正则片段 | 典型用途 |
|---|---|---|
Numeric(size) | [0-9]{n} | 纯数字令牌 |
Hex(size) | [a-f0-9]{n} | 十六进制令牌 |
AlphaNumeric(size) | [a-z0-9]{n} | 字母数字令牌 |
AlphaNumericExtendedShort(size) | [a-z0-9_-]{n} | 含下划线/连字符 |
AlphaNumericExtended(size) | [a-z0-9=_\-]{n} | 含等号/下划线/连字符 |
AlphaNumericExtendedLong(size) | [a-z0-9\/=_\+\-]{n} | 含斜杠/加号等 |
Hex8_4_4_4_12() | [0-9a-f]{8}-[0-9a-f]{4}-…-{12} | UUID 形态 |
Beamer 的秘密体b_[a-z0-9=_\-]{44}就是通过AlphaNumericExtended("44")生成的字符集拼出来的。secrets.NewSecret(regex)(见 cmd/generate/secrets/regen.go)基于reggen库按给定正则随机生成一个合规的秘密值,用于构造 true positive 样本。
验证部分:真阳性与假阳性
规则文件最后必须调用utils.Validate(r, tps, fps)(见 cmd/generate/config/utils/validate.go)。它的工作方式是:
- 对每一个 true positive(
tps),用单规则检测器执行DetectString,若检测不到任何 finding,则记录 Fatal 日志并终止生成; - 对每一个 false positive(
fps),同样执行检测,若产生了 finding,同样 Fatal 终止。
也就是说,新增规则在生成配置时就会被强制验证——规则必须能命中你提供的正样本、且不能误伤负样本,否则make config/gitleaks.toml直接失败。这样从源头保证了默认配置的质量。
tps建议通过generateSampleSecret/GenerateSampleSecrets构造。前者生成identifier_api_token = "secret"这种单一样本;后者(见 generate.go 中的GenerateSampleSecrets)则一次性生成覆盖 INI、JSON、XML、YAML、C#、Go、Java、Kotlin、PHP、Python、Makefile(含=、:=、::=、?=等赋值形式)以及 logstash 等多种写法的样本集,大大增强规则的健壮性。仓库还提供了ValidateWithPaths变体:当规则使用Path过滤时,样本以map[string]string形式同时携带文件路径,检测器通过detect.Fragment{Raw: …, FilePath: …}验证"正则 + 路径"的组合行为。
验证用的检测器由createSingleRuleDetector构建:它会先把关键词统一小写并去重(strings.ToLower+ map 去重),再套用 base.CreateGlobalConfig 中的全局 allowlist 后构造单规则配置。这意味着新规则在开发期就运行在与真实扫描相同的全局豁免规则之下,行为可预期。
四、第二步:在cmd/generate/config/main.go中注册规则
创建好规则文件后,打开 cmd/generate/config/main.go,在main()的configRulesslice 中追加rules.Beamer(),。请尽量按字母序插入——例如rules.Beamer()就位于rules.BittrexSecretKey()与rules.CodecovAccessToken()之间。
从main.go的后续逻辑可以看到注册环节附带的三重保障:
- 规则自检:遍历
configRules时对每条规则调用rule.Validate()(config/rule.go 中的实现会检查:RuleID非空;regex与path至少有一个,否则"该规则将毫无效果";secretGroup不能超过正则的捕获组数量)。校验失败会输出带 rule-id 的 Fatal 日志并退出; - ID 唯一性检查:以
RuleID为键存入ruleLookUpmap,若发现重复 ID 直接 Fatal——保证生成出的 TOML 中每条[[rules]]的id全局唯一; - allowlist 归一化:对规则级与全局 allowlist 中的
Commits与StopWords做排序,保证多次生成结果稳定可复现。
最后程序用base.CreateGlobalConfig()构造带全局 allowlist 的配置对象,并把ruleLookUp注入其中,通过tmpl.Execute渲染出完整的 TOML 文件。
五、第三步:运行make config/gitleaks.toml重新生成配置
注册完成后,在仓库根目录执行:
make config/gitleaks.toml该目标在 Makefile 中定义,依赖cmd/generate/config下所有文件,执行go generate ./...。main.go顶部的//go:generate go run $GOFILE ../../../config/gitleaks.toml指令会把生成结果输出到 config/gitleaks.toml。注意,main.go运行时要求命令行参数指定输出路径,go generate已代为传入;若手动运行则需提供路径参数,否则程序会向 stderr 输出错误并以状态码 2 退出。
六、第四步:检查生成的config/gitleaks.toml
生成完成后,打开 config/gitleaks.toml 检查新规则。以beamer-api-token为例(位于文件中 L243-L247),实际渲染结果如下:
[[rules]] id = "beamer-api-token" description = "Detected a Beamer API token, potentially compromising content management and exposing sensitive notifications and updates." regex = '''(?i)[\w.-]{0,50}?(?:beamer)(?:[ \t\w.-]{0,20})[\s'"]{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\x60'"\s=]{0,5}(b_[a-z0-9=_\-]{44})(?:[\x60'"\s;]|\\[nr]|$)''' keywords = ["beamer"]可以看到:RuleID渲染为id,Description原样保留,GenerateSemiGenericRegex拼装出的完整正则渲染进regex字段(捕获组即为秘密体),Keywords渲染为keywords。如果规则设置了Entropy、SecretGroup、Path、Tags或规则级 allowlist,也会按 config.tmpl 的规则分别渲染为对应 TOML 字段。
minVersion字段也值得留意:模板中固定写入minVersion = "v8.25.0",它表示运行该配置所需的最低 Gitleaks 版本,版本过旧时会记录警告并提示部分配置功能可能不生效。同时建议确认生成的规则在全局 allowlist(由 base/config.go 提供)之下不会误伤常见占位符、环境变量引用、插值变量等场景,相关豁免行为有 config_test.go 中的TestConfigAllowlistRegexes与TestConfigAllowlistPaths做回归保障。
七、第五步:提交 Pull Request
确认新规则在 config/gitleaks.toml 中渲染正确、全量测试通过后,即可提交 PR,并在 PR 描述中链接对应的 issue。提交时应同时包含两部分改动:
- 新增的规则源码文件(如
cmd/generate/config/rules/{provider}.go); - 重新生成的 config/gitleaks.toml(不要手工编辑,必须由生成器产出,否则下一轮
make config/gitleaks.toml会覆盖手改内容)。
遵循"改源码、跑生成、验结果、提 PR"这条流程,就能以最小成本为 Gitleaks 的默认规则集持续添砖加瓦,同时借助内置的规则校验与真/假阳性验证机制,确保每一条新规则在上线前都经过严格的质量把关。
- 应用安全
- 供应链安全
【免费下载链接】gitleaks
Find secrets with Gitleaks 🔑
相关推荐
如何为TruffleHog添加新的凭证检测器:完整贡献指南
如何为TruffleHog添加新的凭证检测器:完整贡献指南 TruffleHog是一款强大的开源凭证嗅探工具,能够帮助开发者在代码中发现泄露的敏感信息。本文将详
应用安全安全与开源治理漏洞扫描RemBERT vs mBERT对比分析:为什么分离嵌入能提升模型性能
RemBERT vs mBERT对比分析:为什么分离嵌入能提升模型性能 RemBERT和mBERT作为多语言预训练模型的代表,在跨语言自然语言处理任务中发挥着重
终极Alex.js贡献指南:如何为包容性写作工具添加新规则
终极Alex.js贡献指南:如何为包容性写作工具添加新规则 Alex.js是一款强大的包容性写作工具,能够帮助开发者和内容创作者识别并替换文本中可能冒犯他人的表
开发工具Lint
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考