jay-tank/hookseal
GitHub: jay-tank/hookseal
hookseal 是一个零配置的静态扫描门禁,在部署前检测从未验证签名的 webhook 处理程序,防止伪造事件到达生产环境。
Stars: 0 | Forks: 0
# hookseal
**在部署前,找出那些从不验证签名的 webhook 处理程序。**
一个不验证其签名的 webhook endpoint 会接受 *任何* 到达该
URL 的 POST 请求。发现该 endpoint 的攻击者可以伪造事件——例如伪造的
`checkout.session.completed`、伪造的 `payment_intent.succeeded`——而你的应用
会照单全收并执行。这是一个高危漏洞,很容易引入,而且正如
每份指南所强调的,[大多数开发者都跳过了此检查](https://anethoth.com/verify-webhook-signatures/)。
甚至还有一个针对相关失误的现有 CVE——一个 *空* 的签名密钥
([CVE-2026-41432](https://github.com/advisories/GHSA-xff3-5c9p-2mr4))。
`hookseal` 是一个零配置的门禁,它能扫描你的代码以查找 webhook 接收器,
并标记出其中未验证签名的部分。
```
$ hookseal .
● 1 forgeable webhook(s):
src/routes/stripe.js:14 Stripe webhook received but the signature is never verified.
↳ This endpoint accepts any POST that reaches it — an attacker can forge Stripe
events. Verify the signature before trusting the payload.
[HS001 Stripe]
1 blocker · 0 warnings
```
当发现可伪造的 webhook 时,它会返回退出代码 `1`,因此可以直接将其接入
pre-commit 或 CI 中。
## 工作原理
检测过程简单且 **与语言无关**。服务商的签名 header
(`Stripe-Signature`、`X-Hub-Signature-256`、`X-Slack-Signature`、
`X-Shopify-Hmac-Sha256`、`X-Twilio-Signature`、……)是一个高信号标记,表明
某个文件正在接收该服务商的 webhook——因为该 header 几乎
不会因为任何其他原因被提及。如果此类文件中 **没有** 包含任何已知的
验证原语(服务商的 SDK 验证器,或像
`hmac.compare_digest` / `crypto.timingSafeEqual` 这样的原生 HMAC 比较),那么该 webhook 就是可伪造的。
无需执行任何代码,不进行任何网络调用,也无需任何配置。
它是一个单一的静态二进制文件。
**覆盖的服务商:** Stripe、GitHub、Shopify、Slack、Twilio、Svix、Square —
以及任何使用原生 HMAC 进行验证的服务商。
## 安装
```
go install github.com/jay-tank/hookseal@latest
```
或者从源码构建:`go build -o hookseal .`
## 用法
```
hookseal # scan the current directory
hookseal ./src # scan a path
hookseal --strict # treat warnings (e.g. empty secret) as failures too
hookseal --json # machine-readable output
```
### 在 CI 中
```
- run: go run github.com/jay-tank/hookseal@latest ./ --strict
```
退出代码:`0` 安全 · `1` 发现可伪造的 webhook(或在使用 `--strict` 时的任何发现项)
· `2` 用法错误。
## 规则
| 规则 | 严重程度 | 说明 |
| :--- | :--- | :--- |
| HS001 | blocker | 接收到了服务商的 webhook,但从未验证其签名 |
| HS003 | warning | webhook 签名密钥被设置为空字符串(验证变成了空操作) |
## 抑制误报
hookseal 是一个启发式检查门禁:它会独立查看每个文件。如果你
在共享的 middleware(另一个文件)中验证了
签名,请在处理程序文件中的任意位置添加 `hookseal:ignore` 注释,或者在
`.hooksealignore` 文件中列出路径子串(每行一个,使用 `#` 进行注释)。
## 适用范围
hookseal 能很好地回答一个问题——*“这个 webhook 接收器到底有没有
验证它的签名?”*——它跨越多种语言,作为一个快速的静态门禁运行。它 **不能**
证明你的验证过程是正确的(比如使用了正确的密钥、进行了常数时间比较、在解析前读取了原始 body);它只能证明检查 *确实存在*。仅仅这一个问题
就能捕获最常见且最危险的错误:完全没有检查。
## 许可证
MIT © Jay Tank
标签:EVTX分析, Go, Ruby工具, Webhook验证, 代码安全扫描, 日志审计, 错误基检测, 静态代码分析