往期文章

【Web安全】一次性搞懂 ReDOS 漏洞原理/检测/防御

【Web安全】一次性搞懂 XSS 漏洞原理/检测/防御

【Web安全】一次性搞懂 CSRF 漏洞原理/检测/防御

【Web安全】一次性搞懂 SSRF 漏洞原理/检测/防御

【Web安全】一次性搞懂越权漏洞原理/检测/防御

前言

在Web应用的逻辑漏洞体系中,支付漏洞因其直接关联资金安全而成为攻击者的重点目标。这类漏洞并非依赖复杂的代码执行,而是利用支付流程中对关键参数(如金额、商品标识、订单状态)的校验缺陷,让攻击者以非正常方式完成支付(如低价购买高价商品、免费获取付费服务)。本文将深入解析支付漏洞的原理、典型场景及防御策略。

一、漏洞本质

支付漏洞的核心是服务器对支付流程中关键参数的校验逻辑失效。正常支付流程中,商品金额、订单状态、支付方式等核心信息需经过严格的合法性与一致性校验;而存在漏洞时,系统可能直接信任客户端传递的参数、省略关键环节的验证,或对业务规则的边界判断模糊,导致攻击者可通过篡改参数等方式绕过正常支付逻辑,获取不当利益。

简单来说,就是“该算的钱算错了,该拦的支付放过了”。

二、攻击原理

正常支付流程

  1. 用户选择商品并提交购买请求;
  2. 服务器生成订单(包含商品ID、金额、折扣、订单类型、状态等关键信息),返回订单详情;
  3. 用户发起支付(如调用支付接口、跳转第三方支付);
  4. 服务器校验支付信息(金额是否匹配订单、订单状态是否为“待支付”等);
  5. 支付完成后,服务器更新订单状态为“已支付”,并触发商品交付逻辑。

漏洞触发流程

支付漏洞的核心在于某一环节的校验缺失,典型链路如下:

  • 攻击者在订单生成阶段抓取请求(如包含price=100的订单创建请求);
  • 篡改关键参数(如将price=100改为price=1);
  • 服务器未重新校验参数合法性(如未根据商品ID重新计算金额),直接按篡改后参数生成订单;
  • 攻击者按篡改后金额完成支付,获取原价商品或服务。

攻击链路可概括为:
攻击者 → 抓取订单生成请求 → 篡改支付相关参数 → 服务器未校验 → 以异常价格完成支付

三、抓包的时机选择:生成订单时

支付流程中,订单生成阶段是抓包的关键时机。原因在于:
订单生成时,系统会将商品信息(ID、单价)、用户信息(会员等级、优惠券)、活动规则(折扣、满减)等整合为订单参数(如goods_id=101&price=299&discount=0.9&order_type=1),这些参数直接决定后续支付金额和权益。

若此时未对参数进行服务器端固化,攻击者可通过 BurpSuite 工具抓取请求,篡改参数后重放,而后续的支付、订单确认等环节可能基于已篡改的订单信息处理,最终导致支付漏洞。

例如:用户购买“299元运动鞋”,生成订单的请求为POST /api/createOrder {goods_id:101, price:299},攻击者抓包后将price改为9.9,若服务器直接信任该参数,订单金额就会被改为9.9元,攻击者支付后即可获得商品。

四、风险场景

支付漏洞的风险场景因业务逻辑不同而多样,以下为典型场景:

1. 隐藏商品购买(开发人员预留的测试商品)

开发阶段,工程师常预留测试商品(如0元商品、内部折扣商品)用于功能测试,若测试完成后未删除或隐藏,且后端未限制访问权限,攻击者可能通过篡改商品ID访问这些隐藏商品。

典型案例
某电商平台开发时预留测试商品goods_id=9999(原价1000元,测试价0元),但未从商品列表中移除。攻击者通过抓包发现正常商品请求为goods_id=100-200,尝试将goods_id改为9999后提交订单,服务器未校验该商品是否对普通用户可见,直接生成0元订单,攻击者支付0元即可获得商品。

2. 付费功能免费使用(添加付费参数:JS中查询、先买个会员抓包查看)

付费功能(如会员服务、高级工具)的权限控制常依赖参数标识(如is_vip=0代表非会员,service_type=free代表免费服务),若服务器未校验参数与用户实际权限的一致性,攻击者可通过篡改参数绕过付费验证。

两种常见实现方式

  • JS中查询参数:前端JS代码可能隐藏付费参数(如pay_status=0代表未付费),攻击者通过查看JS源码发现后,在请求中改为pay_status=1,服务器直接信任该参数,允许免费使用付费功能(如高清视频、高级模板)。
  • 抓包对比参数:攻击者先正常购买低价会员(如1元体验会员),抓取会员权限请求(如vip_level=1),后续将普通账号的请求参数改为vip_level=3(高级会员),若服务器未校验用户实际会员等级,即可免费享受高级权益。

3. 修改订单类型(0 改成 -1、1、2、3)

订单类型参数(如order_type)通常关联不同的价格规则(如0=普通订单1=会员折扣单2=活动特惠单-1=测试订单),若服务器未限制order_type的合法取值范围,攻击者篡改类型值可触发异常价格计算。

典型案例
某平台order_type=0时商品按原价计算(100元),order_type=-1为内部测试订单(默认价格0元)。攻击者在生成订单时,将order_type=0改为order_type=-1,服务器未校验该类型是否允许普通用户使用,直接按0元生成订单,导致攻击者免费获取商品。

注:实际在SRC挖掘该类型漏洞时,不要把 1 改成 0 发现没用就放弃,可以多尝试几个值。

4. 修改通用参数(自动计算最终折扣)

系统常根据优惠券、会员等级自动计算最终折扣(如discount=0.8代表8折、coupon_id=100代表减50元),若服务器未校验折扣参数的合法性(如是否存在该优惠券、折扣是否符合规则),攻击者可篡改参数降低支付金额。

典型案例
用户购买1000元商品,使用8折券后应付800元,请求参数为discount=0.8&coupon_id=100。攻击者抓包后将discount改为0.1,并伪造coupon_id=999(不存在的1000元优惠券),服务器未重新校验折扣合理性及优惠券有效性,直接计算金额为1000×0.1 - 1000 = -900元(甚至倒赚),导致支付逻辑异常。

五、检测方式

1. 黑盒测试:模拟攻击流程

  • 识别关键参数:在订单生成环节,抓取请求并标记支付相关参数(如goods_idpriceorder_typediscountcoupon_id)。
  • 执行参数篡改
    • 篡改金额(如price=100price=1);
    • 替换商品ID(尝试非公开ID,如99990000);
    • 修改订单类型(如0-13);
    • 伪造折扣参数(如discount=0.01coupon_id=9999)。
  • 验证结果:提交篡改后请求,若订单金额异常、可访问隐藏商品或免费使用付费功能,说明存在漏洞。

2. 白盒审计:代码层校验逻辑排查

  • 检查订单生成接口(如createOrder)是否对关键参数进行服务器端重算:
    • 金额是否基于goods_id从数据库查询后计算,而非直接使用客户端price
    • order_type是否限制在合法枚举值内(如仅允许0、1、2);
    • 折扣和优惠券是否通过服务器端接口验证有效性(如coupon_id是否存在、是否在有效期内)。
  • 检查支付回调逻辑:是否验证支付金额与订单金额的一致性(避免支付1元却确认100元订单)。

六、防御方案

支付漏洞的防御核心是服务器端“绝对掌控”关键参数,不依赖客户端传递的数据,具体措施如下:

1. 严格校验关键参数

  • 金额与商品强绑定:服务器端根据goods_id从数据库查询单价,结合商品数量、活动规则重新计算金额,忽略客户端传递的price参数。
  • 限制参数取值范围:对order_typediscount等参数设置白名单(如order_type仅允许0、1、2),拒绝非法值。
  • 校验权限与参数匹配性:会员等级、优惠券等参数需与当前用户信息比对(如vip_level必须从用户数据库查询,而非使用客户端值)。

2. 订单信息固化与签名

  • 生成订单时,对关键参数(goods_id、计算后金额、order_type)进行加密签名(如使用安全的哈希算法(如SHA256)加盐),并将签名存入订单记录。
  • 后续支付、确认环节需验证签名,若参数被篡改,签名不匹配则拒绝处理。

3. 管理商品与订单合法性

  • 维护“合法商品列表”,拒绝不在列表中的goods_id(如删除测试商品,或标记为“仅内部可见”并校验访问权限)。
  • 订单状态流转需严格校验(如“已支付”状态只能由支付回调接口更新,禁止客户端直接修改)。

4. 日志与监控

  • 记录所有订单生成、支付、参数修改的操作日志(包含用户ID、IP、参数原值与篡改值、操作时间)。
  • 对异常行为实时告警(如金额骤降90%、使用不存在的商品ID、频繁修改order_type)。

七、总结

支付漏洞是逻辑漏洞中危害最直接的类型,其本质是服务器对支付流程中关键参数的校验缺失。从隐藏商品的非法访问到折扣参数的恶意篡改,攻击者的核心手段始终围绕“篡改订单生成阶段的参数”,而防御的关键在于让服务器成为参数的唯一决策者

开发人员需牢记:客户端传递的任何支付相关参数都不可信,必须通过服务器端的重新计算、权限校验、签名验证来确保支付逻辑的完整性。只有将“不信任客户端”的原则贯穿支付流程设计,才能有效防范支付漏洞,保障资金安全。

本文是「Web安全基础」系列的第 6 篇,点击专栏导航查看全部系列内容。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐