Webhook安全与签名验证最佳实践概述Webhook易受伪造与重放攻击影响。通过HMAC签名、时间戳容差和幂等键可显著降低风险。签名规范签名算法:`HMAC-SHA256`参与字段:`timestamp`、`method`、`path`、`bodySHA256`头部:`X-Signature`、`X-Timestamp`容差窗口:建议 `<= 300s`请求规范化与验签import { createHmac, createHash } from 'crypto'
function sha256Hex(data: string): string {
return createHash('sha256').update(data).digest('hex')
}
function buildCanonicalString(ts: string, method: string, path: string, body: string): string {
const bodyHash = sha256Hex(body || '')
return [ts, method.toUpperCase(), path, bodyHash].join('\n')
}
function sign(secret: string, canonical: string): string {
return createHmac('sha256', secret).update(canonical).digest('hex')
}
function verifySignature(secret: string, req: { headers: Record<string, string>; method: string; path: string; body: string }): boolean {
const ts = req.headers['x-timestamp']
const sig = req.headers['x-signature']
if (!ts || !sig) return false
if (Math.abs(Date.now() - Number(ts)) > 300_000) return false
const canonical = buildCanonicalString(ts, req.method, req.path, req.body)
const expect = sign(secret, canonical)
return timingSafeEqualHex(expect, sig)
}
function timingSafeEqualHex(a: string, b: string): boolean {
const ab = Buffer.from(a, 'hex')
const bb = Buffer.from(b, 'hex')
if (ab.length !== bb.length) return false
return crypto.timingSafeEqual(ab, bb)
}
重放防护与幂等使用 `X-Idempotency-Key` 存储近窗口的请求指纹结合 `timestamp` 与请求哈希作为键,重复请求直接拒绝来源与网络校验配置IP白名单或签名公钥轮换策略对回调域名使用HTTPS与证书固定(Pinning)运维要点对失败验签与重放命中进行告警与审计对密钥启用定期轮换与分环境分密钥提供签名示例与SDK,统一时间源与规范化逻辑以上实践可在通用平台场景下实现稳健的Webhook安全校验与重放防护。

发表评论 取消回复