Webhook 被录包重放怎么防,时间戳校验怎么做
现象#
抓包工具把一条合法的 orders/create 原样重发三次,服务端验签每次通过、每次都建了一笔订单;日志里连 Webhook-Id 都完全相同,却没有被拦住。
原因#
- HMAC 只证明 body 与 secret 匹配,不证明请求是新的,合法报文可以被无限重放
- 没有给 X-Shopify-Webhook-Id 建唯一索引,同一份报文进来多少次就写多少次
- 只按 payload 里的 order id 去重,业务代码先插后查,并发时仍会写出第二条
- X-Shopify-Triggered-At 是带微秒的 ISO 8601 字符串,按字符串比大小会判错
处理步骤#
- 把
X-Shopify-Webhook-Id设为唯一索引,插入冲突即视为重复并回 200 - 解析
X-Shopify-Triggered-At为时间对象,与服务器时间相差超过 5 分钟直接 401 - 服务器开启 NTP 校时,漂移超过窗口会把正常投递也误判成过期
- 重复请求只记一条审计日志,不要静默返回 200 了事,方便事后追查
- 用
shopify app webhook trigger连打两次,确认第二次没有新增订单
验收标准#
重放同一条报文时接口回 200 但订单表无新增行,webhook_id 表里始终只有一行记录。
本文由 风格技术 技术团队整理,适用于 Shopify 标准版与 Plus 店铺。Shopify 平台能力迭代较快,具体操作路径与字段以官方文档和店铺后台实际版本为准。