看我如何利用Webhook绕过支付请求
字数 1935 2025-08-18 11:37:11
Webhook支付请求绕过漏洞分析与防御指南
1. Webhook支付机制概述
Webhook是一种由支付服务提供商(如Stripe、Braintree、Recurly等)向商家服务器推送支付状态更新的技术机制。其特点包括:
- 单向通信:仅由支付提供商向商家服务器发送通知
- 用户不可见:普通用户不会直接与Webhook节点交互
- 异步处理:支付结果通过独立通道通知,而非同步响应
典型应用场景:月度订阅服务续费通知、支付成功/失败状态更新、退款处理等。
2. 漏洞发现与分析
2.1 漏洞原理
当支付Webhook端点缺乏足够的安全验证时,攻击者可以:
- 伪造支付成功的Webhook请求
- 直接向商家Webhook端点发送恶意构造的请求
- 使商家系统误认为支付已完成,从而获得未付费的服务/产品
2.2 漏洞复现步骤
-
识别Webhook端点:
- 常见路径:
/api/webhooks/stripe,/api/payments/webhook,/api/stripeWebhook - 通过JS文件、API文档或GitHub代码库发现
- 常见路径:
-
构造测试请求:
PUT /api/webhooks/stripe HTTP/1.1 Host: target.com Content-Type: application/json { "type": "invoice.payment_succeeded", "data": { "object": { "customer": "attacker_controlled_id", "paid": true, "amount_paid": 9999 } } } -
观察响应:
- 成功响应通常包含状态码200及成功信息
- 漏洞存在时,系统会错误更新订阅状态
2.3 漏洞成因
-
缺乏请求验证:
- 未验证请求来源的真实性
- 未检查数字签名
-
文档误导:
- 支付提供商API文档中的示例代码常省略安全验证
- 开发者直接复制粘贴导致漏洞
-
默认不安全:
- 多数支付平台Webhook默认不强制安全验证
- 安全措施需要额外配置
3. 主流支付平台安全机制对比
| 支付平台 | 验证机制 | 缺陷 |
|---|---|---|
| Stripe | 可选签名验证 | 默认不强制,文档示例常省略 |
| Braintree | 强制代码库验证 | 相对安全,需正确集成 |
| Recurly | HTTP基础认证+IP白名单 | IP欺骗可能,多账号攻击 |
4. 攻击面挖掘方法
4.1 Webhook端点发现技术
-
前端代码分析:
- 搜索包含"webhook"或"payment"的JavaScript文件
- 分析前端支付流程中的API调用
-
文档与代码库:
- 检查目标组织的GitHub公开仓库
- 查阅内部API文档(如有泄露)
-
路径爆破:
/api/[payment_provider]/webhook /api/webhooks/[provider] /api/payments/callback /api/subscriptions/notify -
历史漏洞参考:
- 相同支付平台的集成可能使用相似实现
4.2 测试用例设计
-
基础测试:
- 发送空JSON请求观察错误响应
- 尝试不同HTTP方法(POST/PUT)
-
数据篡改:
- 修改customer ID为攻击者账户
- 修改amount_paid为0或负值
- 添加paid: true字段
-
签名绕过:
- 删除/修改签名头(x-signature等)
- 使用无效签名格式
5. 防御方案
5.1 基本防护措施
-
强制签名验证:
# Stripe示例 endpoint_secret = 'whsec_...' payload = request.body sig_header = request.headers['stripe-signature'] try: event = stripe.Webhook.construct_event( payload, sig_header, endpoint_secret ) except ValueError as e: return HttpResponse(status=400) -
IP白名单:
- 仅接受来自支付提供商官方IP的请求
- 定期更新IP列表
-
请求认证:
- HTTP Basic/Digest认证
- 自定义认证头
5.2 高级防护策略
-
幂等性处理:
- 记录已处理的Webhook事件ID
- 防止重放攻击
-
业务逻辑验证:
if webhook_event.customer_id != get_customer_from_db(webhook_event.invoice_id): log_suspicious_activity() return HttpResponse(status=403) -
多层验证:
- 签名验证 + IP白名单 + 业务逻辑检查
- 防御深度原则
5.3 开发最佳实践
-
安全默认配置:
- 将签名验证设为必选项而非可选项
- 提供安全的示例代码
-
敏感操作二次确认:
- Webhook触发重要操作前,主动查询支付状态
-
监控与告警:
- 记录所有Webhook请求
- 异常模式实时告警
6. 支付平台特定配置指南
6.1 Stripe安全配置
-
获取并验证签名:
const event = stripe.webhooks.constructEvent( request.body, signature, endpointSecret ); -
启用端点密钥轮换
-
配置Webhook端点为受保护路由
6.2 Braintree安全实践
-
使用官方SDK处理Webhook:
webhook_notification = Braintree::WebhookNotification.parse( params[:bt_signature], params[:bt_payload] ) -
禁用直接JSON解析
6.3 Recurly加固建议
- 启用HTTP基础认证
- 配置严格的IP白名单
- 监控多账号关联活动
7. 漏洞检测清单
- [ ] Webhook端点是否可未经验证访问
- [ ] 是否验证请求签名
- [ ] 是否实施IP限制
- [ ] 业务参数是否与系统状态交叉验证
- [ ] 是否有防重放机制
- [ ] 是否记录所有Webhook活动
- [ ] 异常请求是否触发告警
8. 总结
支付Webhook漏洞源于安全验证的缺失,攻击者可利用此漏洞获取未付费服务。防护关键在于:
- 强制实施签名验证 - 所有支付平台都应验证请求真实性
- 深度防御 - 组合多种验证机制
- 安全开发实践 - 避免直接使用文档中的不安全示例
- 持续监控 - 检测异常Webhook活动
支付提供商和商家必须共同承担责任,确保Webhook实现的安全性。