本节以SQL注入漏洞和支付漏洞为案例,介绍这两种安全漏洞的形成原理、如何通过测试模拟攻击,以及对应的防范措施。
3.4.1 案例1:SQL注入漏洞
05
SQL注入防范
作为测试人员,我们除了发现缺陷,还可以提出缺陷修复的建议方案。以下方式可以避免出现SQL注入漏洞,可以作为我们的建议方案提供给开发人员。
(1)绑定变量,使用预编译语句。
MySQL的MySQL驱动提供了预编译语句的支持,不同的编程语言分别有不同的使用预编译语句的方法,使用预编译的SQL语句的语义不会发生改变。
绑定变量通过使用占位符(通常是问号 “?” 或命名参数)来代替具体的值,然后在执行 SQL 语句时将实际的值传递给这些占位符。
例如:“SELECT * FROM users WHERE username =?”。在执行这个语句时,开发人员可以将具体的用户名作为参数传递给数据库执行引擎。
(2)加强对用户输入内容的检查与验证。
例如,通过正则表达式过滤传入的参数,严格检查参数值类型和格式,过滤特殊字符等。
(3)严格限制数据库权限。
例如,只为应用分配限制权限的数据库账号,并且对数据库的所有访问记录日志,以便做安全审计。
(4)敏感信息加密存储。
例如,对敏感信息进行加密存储。这样,即使因SQL注入漏洞导致数据泄露,获取数据的人也很难解密数据,从而在一定程度上保证数据安全。
3.4.2 案例2:支付漏洞
2018年7月4日,微信支付的SDK曝出重大漏洞——XXE(XML External Entity Injection,XML外部实体注入漏洞)。
通过该漏洞,攻击者可以获取服务器中目录结构、文件内容,如代码、各种私钥等。获取这些信息以后,攻击者便可以通过修改支付请求中的数据,使支付金额被错误地验证为 0 元,实现“0元也能买买买”。
而早在2012年,阿里旺旺使用短信旺旺中心对短信条数进行充值时,就存在可以通过工具修改支付价格信息的漏洞,导致用户只需要1元人民币就可购买原100元才能购买的1200条短信。
对于信息安全高度重视,又以支付、电商作为其核心业务的微信、淘宝等应用尚且存在支付漏洞,更不敢想象资金、人才、技术上均有差距的中小企业的支付应用在使用过程中,可能存在什么漏洞了。
除了腾讯和阿里巴巴,原乌云漏洞平台也曾曝光过京东、新浪、苏宁、必胜客、肯德基、网通、国美、又拍网、拉卡拉、豆丁网等平台存在支付漏洞。
支付漏洞一直以来都是风险极高的安全问题,因为直接涉及经济损失。这里列举几类常见的支付漏洞。
01
修改支付价格
从购买商品到支付一般有3个步骤,下单→确认信息→支付,这3个步骤进行时攻击者都可能通过抓包来修改商品价格。
前面两步可能有验证机制,攻击者可以在最后一步付款时进行抓包,并尝试修改金额,因此如果没有在最后一步做好验证,就会存在支付漏洞。
例如,将原本高价值商品的支付价格,修改为0或者0.01,如果支付成功,就通过漏洞实现了以0元或0.01元购买高价值商品的目的。这就是“0元支付漏洞”或“1分钱支付漏洞”。
另外,商品的金额一般会用int类型来定义,而在Java语言中int的最大值为2147483647。
如果金额修改为2147483648,而程序又没有对越界做判断,就可能造成整数溢出,从而出现支付状态异常甚至导致支付成功的情况。
02
修改支付状态
在正常的支付流程中,用户发起支付请求,支付平台进行处理并将支付结果返回给商家系统。
商家系统根据支付结果更新订单的支付状态,如从 “未支付” 变为 “已支付”。
然而,如果商家系统在处理支付结果时没有进行充分的验证和安全防护,攻击者就有可能通过篡改支付结果的参数来欺骗商家系统,使其错误地将订单状态更新为 “已支付”。
例如,用户购买A商品,攻击者在其支付时抓包,观察包中是否有字段p来表明A商品是否被支付,p=1代表支付成功,p=0代表支付不成功,那么攻击者就可以将未支付的订单中的字段p直接修改为p=1,使订单处于支付成功状态。
03
修改购买数量
通常,在支付过程中,数量决定了订单总金额,但如果订单没有对商品数量做严格校验,也可能会出现漏洞。
例如,1件商品价格为10元,用户下单1件商品,此时应支付10元,而在实际支付时,攻击者可以尝试通过抓包修改订单中商品的数量,将1修改为2甚至更多。
如果订单没有对商品数量做校验,就有可能出现订单中包括2件甚至多件商品,而支付的金额仍然为1件商品的金额的情况。
另外,如果将购买数量修改为负数,总额的算法依然是“购买数量×单价=总价”,这就会导致支付金额为负。若支付成功,则可能返还相应的积分/金币到用户的账户中。
04
越权支付
假设商品A价格是50元,id=1,商品B价格是200元,id=2,如果下单购买商品A,应付50元,但在支付时,攻击者将订单中商品A的id换成商品B的,如果能修改成功,那么可能出现只支付了买商品A的金额,却成功买到了商品B的情况。
另外,支付接口如果带有用户id等信息,攻击者尝试将其修改为其他人的id,可能会出现“拿他人的钱包买东西”的情况。
05
修改优惠券、运费
攻击者在支付过程中可以通过修改优惠券、运费等信息让平台遭受经济损失,例如:
● 修改优惠券金额,使小额优惠券变成大额优惠券;
● 修改优惠券有效期、使用范围、适用规则等,使原本失效或不在使用范围的优惠券能够使用;
● 修改运费价格,将运费价格修改为负,来抵消商品价格。
06
请求重放
购买成功后,重放请求,使得购买商品一直增加。例如,攻击者在Web端下单商品并支付,然后用抓包工具抓取接口请求,再通过Charles等工具设置并发数及执行次数,执行重放请求,就可能重复生成订单,而不用再次支付。
通过介绍不同类型的支付漏洞,可以看到支付漏洞的危害很大,稍有不慎,就会造成直接的资金损失,这里介绍一些支付漏洞的预防手段:
● 在服务器端校验商品价格、优惠券、运费、订单金额等信息;
● 校验价格、数量参数是否符合设计需求,例如产品数量只能为正整数,并限制购买数量;
● 与第三方支付平台核对实际待支付的金额是否与订单金额一致,如果不一致,则取消交易;
● 对支付参数进行数字签名及验证,防止数据被篡改;
● 当订单金额超过一定阈值时,设置人工审核。
安全性测试是评估软件系统的安全性的过程,用于发现软件应用中的漏洞、威胁和风险,防止攻击者的恶意攻击。
这些漏洞、威胁和风险可能导致数据泄露等信息安全事故,给企业和个人带来经济损失和声誉损失,严重的还会影响到国家安全。
安全问题更多的是安全意识问题,而不是技术问题,因此加强研发过程中的人员安全意识,是防止安全问题产生的有效方式。
本书作者:孔令云
......
点击阅读原文,查看独家连载

