PayPal智能按钮onApprove跳转未授权访问安全问题咨询
PayPal智能按钮支付流程安全加固方案
核心问题在于前端回调结果不可信任,攻击者可以完全绕过PayPal支付流程,直接调用交付接口,所有校验和交付逻辑必须下沉到后端处理,具体可按以下步骤改造:
- 第一步:修改前端onApprove回调逻辑,取消直接跳转到固定交付地址的操作,将回调拿到的PayPal订单ID、对应商品ID等参数,通过POST请求提交到你自己服务的后端校验接口,请求需携带CSRF令牌防止跨站请求伪造。
修改后的前端示例代码:
onApprove: function(data, actions) { return actions.order.capture().then(function(orderData) { // 提交订单信息到后端校验 fetch('/api/verify-paypal-order', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': '你的站点CSRF令牌' }, body: JSON.stringify({ orderId: data.orderID, productId: 2323 }) }).then(res => res.json()).then(verifyResult => { if (verifyResult.success) { // 后端校验通过后再跳转,跳转地址由后端返回,不要前端写死 window.location.href = verifyResult.deliverUrl; } else { alert('支付校验失败,请联系客服处理'); } }) }); }
第二步:后端增加支付校验逻辑,收到前端提交的订单信息后,主动调用PayPal官方订单查询接口核验订单真实性,必须同时满足以下所有条件才判定为支付有效:
- 订单状态为已完成(COMPLETED)
- 订单内的商品金额、商品标识和你站点对应商品的信息完全匹配
- 该订单之前没有被处理过(做幂等校验,避免重复交付)
- 订单关联的支付用户和你站点当前登录的用户一致
第三步:后端校验支付有效后,生成一次性有效、带时效的访问令牌,令牌存入数据库并关联对应用户、对应商品、过期时间(建议设置为5分钟以内)、使用状态(初始为未使用),将令牌作为参数拼接在交付链接中返回给前端,不要直接返回裸的交付地址。
第四步:改造服务交付接口(即原
oneserviceBought接口),增加以下校验逻辑,所有校验通过后再交付对应服务:- 校验当前用户登录态,确认是下单对应账号
- 校验链接携带的令牌是否存在、未过期、未被使用
- 校验令牌关联的商品ID和请求的ID一致
- 校验完成后立即标记令牌为已使用,避免被重复调用
额外加固建议:
- 不要把固定的服务交付地址暴露在前端代码、静态资源中
- 交付接口限制请求频次,防止攻击者暴力枚举令牌
- 所有订单操作留痕,出现异常可以快速追溯
内容的提问来源于stack exchange,提问作者user2301515
相关产品推荐
相关产品推荐

