微信公众号支付漏洞成因探究

2016-05-14 04:40敖毅
网络空间安全 2016年7期

【 摘 要 】 微信公众号系统在实现微信支付功能时,如果支付流程设计或系统实现不合理,会造成篡改攻击漏洞或短路攻击漏洞,可以被恶意用户用于发起中间人攻击。论文模拟了利用两种漏洞进行中间人攻击的过程,分析了两种漏洞的形成原理,并提出了防范漏洞的解决方案。

【 关键词 】 微信支付;篡改攻击漏洞;短路攻击漏洞

【 Abstract 】 Neither unreasonable payment process design nor failed system implementwouldlead to the Tampering Vulnerability or the Short-circuit Vulnerability, which could be used to launch the man-in-the-middle attacks by the malicious user. This paper simulates how to use 2 different vulnerabilities to launch MITM attack, describes the principle of each vulnerabilities and puts forward solution to fix them.

【 Keywords 】 wechat pay; tampering vulnerability; short-circuit vulnerability

1 引言

腾讯公司的微信(WeChat)推出公众号、服务号以及微信支付功能后,越来越多的商家通过推出微信公众号,开办微商城,提供微服务等形式依托微信开展商业活动。但是,微信公众号系统在实现微信支付功能时,如果流程设计或系统实现不合理,容易造成支付漏洞,引来恶意用户攻击。

在以往有一起针对微信公众号支付漏洞的恶意用户攻击事件,经估算,这次攻击共造成了约15万元人民币的经济损失。值得指出的是,本文提到的支付漏洞目前在大量微信公众号中仍然存在,需引起高度重视。

2 微信公众号微信支付的中间人攻击模拟

经分析,这次攻击是恶意用户采用中间人攻击的方法,通过网络抓包的手段,利用某微信公众号的微信支付流程中存在的篡改攻击漏洞和短路攻击漏洞,伪造网络请求数据,最终实现了恶意消费。下面将对比该微信公众号的正常支付流程,模拟恶意用户利用漏洞发起中间人攻击的过程。

2.1 微信公众号正常支付流程

该微信公众号设计的正常支付流程共分七步,如图1所示。第一步,通过微信客户端关注微信公众号;第二步,点击微信公众号底部菜单栏中的“购买会员”菜单项;第三步,跳转到“永久VIP会员”购买页面,输入手机号;第四步,点击【立即购买】按钮后,跳转到确认购买页面;第五步,在确认购买页面点击【微信支付】按钮,弹出微信支付对话框;第六步,在微信支付对话框中输入支付密码,进行支付操作;第七步,如果支付成功,会收到消息通知,告知用户购买VIP会员已成功,可以开始使用VIP客户的功能;如果支付失败,将返回第二步。

2.2 恶意用户进行中间人攻击过程模拟

2.2.1 利用篡改攻击漏洞实施中间人攻击

篡改攻击漏洞,是由于系统的接口设计或实现存在缺陷造成的漏洞,导致恶意用户可以通过篡改网络交互数据等方法,达到攻击系统的目的。上述微信公众号支付流程的第四步的设计存在篡改攻击漏洞。

当用户点击【立即购买】按钮,跳转到确认购买页面时,如果使用网络抓包工具Fiddle Web Debugger抓取此时微信公众号提交到后端系统的URL请求,可以在抓取的URL请求中,发现有“totalprice”字段,该字段的值为“12”。这个值与支付流程第五步中显示的价格一致。这意味着如果修改此字段的值,则微信支付系统生成的支付凭证中的金额值也可能会相应修改。尝试在Fiddle中将此值修改为0.01,果然在随后的第五步中,微信支付页面显示为0.01元。随即通过微信实际支付1分钱,该微信公众号即反回支付成功消息,并告知用户已取得了VIP用户的所有特权。

经验证,篡改攻击漏洞也存在于某些电商平台和团购网站的微信公众号中。

2.2.2 利用短路攻击漏洞实施中间人攻击

短路攻击漏洞是由于系统的流程设计或实现存在缺陷造成的漏洞,利用该漏洞,恶意用户可以更改脚本代码,造成代码中的条件判断语句“短路”,只执行条件分支中的某部分语句,达到攻击系统的目的。上述微信公众号支付流程的第五步的设计和实现中存在短路攻击漏洞。

当用户点击【微信支付】按钮,发起微信支付请求时,可以使用Fiddle截获后台服务器返回的页面代码,如代码 1所示。有三种方法可以导致这段代码“短路”:一是将if表达式中的逻辑判断符号“==”修改为赋值符号“=”,使if判断语句变为一个恒真式,达到“短路”的目的;二是直接删除if语句和后面的else语句块,使得无论用户微信支付是否成功,或者是否实际支付,都会提交用户支付成功的信息,并修改用户状态;三是在if判断语句前增加一行代码,直接将res的err_msg属性值赋值为“get_brand_wcpay_request:ok”。

经验证,上面三种方法都可以对该微信公众号实施短路漏洞攻击。值得注意的是,有的微信公众号系统考虑到了第一、二种攻击方法,因此采取将微信支付接口返回的res对象直接提交到后台系统,在后台系统中再根据res.err_msg的值来判断用户是否支付成功。但是由于存在第三种攻击方法,仍然可能造成短路攻击漏洞。

3 微信公众号微信支付漏洞成因剖析

为了保证支付过程安全可靠,腾讯公司给出了微信公众号微信支付的参考业务流程,如图 2所示。对照该业务流程可以看出,造成该微信公众号出现篡改攻击漏洞和短路攻击漏洞的主要原因是,没有按照正确的业务流程设计和实现微信支付功能。

3.1 篡改攻击漏洞分析

按照微信支付业务流程,当用户通过点击微信支付消息或扫描二维码,准备在微信客户端浏览器中打开用于支付的页面时(图 2第二步),将向微信公众号后台系统提交生成支付订单的请求;微信公众号后台系统收到请求后,生成客户订单(图 2第四步);再调用微信支付统一下单API,向微信支付系统提交生成预付单请求,微信支付系统在生成预付单后,返回预付单信息(prepay_id)给微信公众号后台系统(图 2第五步);微信公众号后台系统根据返回的预付单信息(prepay_id)生成JSAPI页面调用的参数并签名(paySign)(图 2第六步)后生成HTML5页面返回用户,等待用户点击进行支付。

导致产生篡改攻击漏洞的主要原因是在上述流程中,“请求生成支付账单”和“生成用户订单”两步间的信息交互设计存在问题。

微信公众号后台系统在生成用于支付的消息或二维码时,通常会使用一个标识号作为前后端交互的依据,这个标识号可以是用户的订单号或产品的产品号。当用户点击消息或扫描二维码请求生成支付订单时,后台系统应根据这个标识号生成对应的订单,包括计算订单的应付金额。

但是部分以提供会员、充值、点卡、外卖等产品的微信公众号系统,由于产品形态单一,而且通常一个产品就是一个订单,因此没有设计独立的标识号,而是将应付金额等敏感数据包含在了前后端交互的信息中;后台系统在收到前端系统的支付请求后,也没有进行必要的验证,就直接将请求数据生成了预付单,这样就会留下篡改攻击漏洞。

3.2 短路攻击漏洞分析

从微信支付业务流程看,从用户确认支付(图 2第九步)到微信客户端展示支付结果(图 2第十五步),共有六个步骤。这其中包含了两个并行任务,用于返回用户支付结果:一是通过异步的方式通知微信公众号后台系统支付结果(图 2第十步),微信公众号后台系统在处理完支付结果后再将处理结果通知微信支付服务(图 2中第十一步);二是通过JS API直接返回支付结果给微信客户端(图 2第十二步)。在公众号支付开发者文档中明确说明,这两个并行处理的任务并“不保证遵循严格的时序,JS API返回值作为触发商户网页跳转的标志,但商户后台应该只在收到微信后台的支付成功回调通知后,才做真正的支付成功的处理”。

因此,当微信支付的JS API返回支付结果后,要验证用户是否实际支付成功,还应向微信公众号的后台系统提交查询用户实际支付结果的请求(图 2第十三步),微信公众号的后台系统通过调用微信支付查询API,查询实际支付结果(图 2第十四步),再根据查询结果执行支付后个性化页面展示。

短路攻击漏洞造成损失的直接原因是恶意用户绕过用户支付结果验证流程,将用户状态修改为已正常支付的状态。系统实现中的两个错误共同导致了短路攻击漏洞:一是错误地使用微信客户端收到的JS API返回结果作为验证用户是否支付的依据;二是在前端的Javascript中调用修改用户支付状态的代码。

分析微信公众号的微信支付页面代码,发现在调用微信支付接口时,都参照了公众号支付开发者文档中提供的示例,如代码 2所示。

从代码 2中可以看出,微信公众号是通过使用微信内置浏览器提供的内置对象WeixinJSBridge调用getBrandWCPayRequest方法来调用微信支付接口。在该方法的回调函数中,可以根据微信支付接口返回的结果res.err_msg进行下一步处理。但是在公众号支付开发者文档中,明确说明:“res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠”。不能保证其绝对可靠的原因是因为Javascript的对象属性是可以在运行时修改。因此,导致短路攻击漏洞的第一个错误是直接将微信客户端收到的JS API返回结果作为验证用户是否支付成功的依据,没有严格按照微信支付业务流程要求,在后台进行支付结果验证,致使验证流程可能被绕过。

导致短路攻击漏洞的第二个错误是将修改用户支付状态的代码放在了前端Javascript代码中(如前文代码 1所示)。由于存在可以绕过支付结果验证环节的可能性,因此这样做既不能保证业务流程的完整性,也不能保证用户状态修改合法。实际上,按照微信支付流程,应该是在微信公众号的后台系统收到微信支付系统的异步通知后才能修改用户支付状态。

4 微信公众号微信支付漏洞的解决方案

要避免微信公众号的微信支付模块中留下篡改攻击漏洞或短路攻击漏洞,需要从系统的设计、实现、运维等多个方面着手。

4.1 前后端模块之间的交互应是系统设计时关注的重点

要保证微信支付的安全,系统设计是关键。在系统设计时,应严格按照公众号支付开发者文档中提供的业务流程,对前后端模块的职责、交互接口、传输协议等进行正确设计。

(1)前后端模块职责分明。前端模块只负责页面的展示和部分的输入校验功能,而订单处理、预付单生成、支付结果处理、账单状态查询等关键功能应放在后端模块。

(2)交互接口最小化。在接口设计时,可遵循RESTful风格,按照HTTP协议规则设计API接口;在传输内容上,只传递订单号或产品号等必要信息,特别是在前端模块向后端模块发起PUT、POST请求时,应避免将价格、数量、总价等可能影响到支付结果的敏感信息包含在内。

(3)选择HTTPS协议作为传输协议。与HTTP协议相比,HTTPS协议具有更好的保密特性,可以防止在传输过程中被获取或篡改信息。

4.2 在系统开发过程中应层层设防,避免留下漏洞

由于程序员个体经验的不足,或者是团队没有采用恰当的软件开发方法,在系统实现阶段往往容易造成微信支付功能出现漏洞。通过层层设防的方式,有助于减少系统开发过程中造成的漏洞。

(1)对前端代码进行必要的分离、混淆和压缩。在实现前端模块时,要充分掌握Javascript语言规范和正确的使用方式,避免因误用留下漏洞;将HTML5代码和Javascript代码分离,有利于对Javascript代码进行独立的管理;借助诸如YUI Compressor、Closure Compiler、uglifyjs等工具软件对Javascript脚本文件进行混淆和压缩,可以增加恶意用户逆向分析和篡改程序的难度。

(2)后端模块必须对请求参数进行校验。对于前端模块传递来的任何请求,后端模块都必须对请求所携带的参数进行校验,包括有效性校验、合规性校验、业务规则校验等,保证请求的合法性。校验通过后才能进行后续处理,以杜绝恶意用户在参数传递过程中实施篡改攻击。

(3)采用验收测试、代码审查等软件工程方法,减少人为因素造成漏洞。验收测试可以模拟软件系统在实际使用场景中的不同运行流程,验证软件的功能质量特性;代码审查通过团队成员间交叉审查源代码,达到弥补个体经验不足,减少系统漏洞,提高代码质量的目的。

4.3 在运维中应通过定期核查保障资金安全

除了在系统的设计和实现时需要考虑周全,小心谨慎外,在运维过程中加强定期核查也是保障资金安全的重要手段。定期核查可以通过对账检查和日志审计等方式进行。

(1)在系统中应提供“对账检查”功能,通过微信支付系统提供的“下载对账单”接口,定期或手动下载对账单。运维人员通过自动或人工比对提交到微信支付系统的订单及金额与微信公众号系统中记录的订单和金额,发现是否存在异常订单支付记录。

(2)系统应提供完备的运行日志,可以对支付过程中的运行情况进行跟踪记录。当发现遭受恶意用户攻击或者资金异常情况时,运维人员可以通过分析系统运行日志,查找问题出现的时间和位置,分析恶意用户的攻击方式,及时修补漏洞。

参考文献

[1] 【微信支付】公众号支付开发者文档[EB/OL]. https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1#.2016.05.18.

[2] 【微信支付】公众号支付开发者文档[EB/OL]. https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_4# . 2016.05.18.

[3] 【微信支付】公众号支付开发者文档[EB/OL]. https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6 . 2016.05.18.

[4] 【微信支付】公众号支付开发者文档[EB/OL]. https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6.2016.05.20.

[5] 【微信支付】公众号支付开发者文档[EB/OL]. https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7.2016.05.20.

作者简介:

敖毅(1976-),男,四川乐山人,管理学博士,解放军南京政治学院军事信息管理系军事信息安全防护实验室副主任,讲师;主要研究方向和关注领域:指挥信息系统、政治工作信息化、军事信息安全。