导读
本文主要基于京东物流的分拣业务平台在生产环境遇到的一些安全类问题,进行定位并采取合适的解决方案进行安全治理,引出对行业内不同业务领域、不同类型系统的安全治理方案的探究,最后笔者也基于自己在金融领域的经验进行了关于API网关治理方案的分享。
写在前面
随着互联网应用的多元化、复杂化、服务化成为显著趋势,越来越多场景中的应用架构采用应用编程接口(API)作为应用间数据传输和控制流程。同时API接口负责传输数据的数据量以及敏感性也在增加。因此针对API的攻击变得越来越频繁和复杂,成为当今不少公司的头号安全威胁。
根据API安全服务提供商Salt Security的最新报告,近66%的企业缺乏基本API安全策略。在过去的几年时间里,市场上已经看到了API面临的风险和攻击的巨大增长,不仅出现了Facebook、T-Mobile等公司的API违规事件,也出现了美国邮政服务(USPS)和Google+的最新漏洞泄露事件。
这给我们敲响了警钟:安全无小事,研发需谨慎!
一、背景
2022年2月14日接收到某A分拣中心一线同事反馈:出现部分解封车无下文的货物在9号至13号之间出现自动验货情况,经询问该分拣中心场地一线人员均未对其验货。
二、发现问题
2.1 锁定实操报文
查询系统日志,根据运单号JDV0055896869XX定位具体请求报文:
图1 验货实操请求日志
2.2 确定IP
查询nginx日志,定位请求IP:
图2 nginx日志
2.3 确认场地
根据集团自研的运维保障统一管理平台-终端探测功能,依据ip定位出场地来源:
图3 终端探测链路
2.4 定位主机
查看路由信息,根据ip和主机绑定关系,定位主机设备:
图4 路由信息
图5 主机信息
2.5 得出结论
某B分拣中心使用HB-TZFJ-33257A此电脑在2022年2月13日17点55分左右使用脚本工具,伪装了HTTP请求报文,将某B分拣中心部分解封车无下文的货物验货至某A分拣中心,构成恶意分拣,使得B分拣中心考核数据转嫁到A分拣中心。
为什么会这样呢?
由于历史发展原因,分拣pda存在wince和android两个版本,由于wince版本可扩展性较差、设备成本较高等原因,计划逐步下线wince版本。wince版本没有接入物流网关,调用的传统的rest 服务,这块未对wince设备访问进行校验拦截,存在漏洞。
最终综合考量未来的推广发展和整改成本等原因,wince版本不再接入物流网关,只在原有的架构设计上增加一层鉴权拦截机制,既保证小部分用户安全过渡使用,又节省了一定的系统改动成本。
三、解决过程
基于sha256摘要算法为服务端RestAPI增加鉴权逻辑,防止非法请求。
具体细节:客户端需要在请求头中携带以下字段信息:
- registerNo-设备或者是身份识别码
- signation 序列号
- siteCode 调用方设备或者是用户所属站点
- timestamp 时间戳
- noceno 随机序列
- opCode 操作码
- authorization 签名
registerNo和siteCode 为调用方身份信息,需要预先在分拣管理系统中进行注册获取,客户端基于header中的字段和body信息排序封装,携带salt值做sha256摘要计算,得到摘要结果作为authorization签名信息,和其他字段一起上送给服务端。服务端接收到请求后,基于同样的算法做sha256摘要计算,如果得到的签名信息跟客户端传输的一样即验证通过,否则为非法请求。
之所以采用这种鉴权方案是因为摘要算法性能较高,满足当前的安全需要,且考虑到升级实施的便捷性(目前客户端有很多版本:android和wince设备)最终选择了此方案。上线鉴权功能后,未携带鉴权逻辑的请求被拦截,系统安全问题得到很好的解决,并且可以根据日志快速定位非法请求来源。
四、行业方案鉴析
行业内关于API鉴权的方案有很多种,笔者基于自己的工作经验梳理了以下三类应用场景:
4.1 B-S架构类系统(网站类)
这类大多以cookie+session或token机制为多,实现一些登录会话等安全管理功能。
4.1.1 cookie+session机制
cookie + session是最传统的API鉴权方式,比如很多网站的登录模块就是靠这种方式实现会话管理。在服务端会生成一个session来保存会话状态,各个session是通过唯一的session_id来标识的,session_id会在响应前端请求时返回给前端,前端将其保存在cookie中,后续的所有请求都会携带cookie传到服务器端,服务器端解析cookie后找到对应的session进行判断是哪个客户端发起的。
其优点是:
比较传统,对开发来说资料较多,语言支持完善。
较易于扩展,外部session存储方案已经非常成熟了(比如Redis)。
缺点是:
性能相于较低:每一个用户经过后端应用认证之后,后端应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。
因为基于cookie来进行用户识别, cookie如果被截获,用户就会很容易受到CSRF攻击;用户如果禁用了浏览器cookie,这套机制就不再适用。
很难跨平台:在移动应用上 session 和 cookie 很难行通,你无法与移动终端共享服务器创建的 session 和 cookie。
总的来说,如果是传统的web网站,且同时认证的人数不是足够大(比如只是内部使用)的都可以用这种方式,很多网站依旧采用该方式。
4.1.2 token机制
token令牌机制是用来代替session的鉴权方案,现在很多API的鉴权都是通过token机制。token机制是服务器端生成的一串加密串发放给客户端,客户端请求服务器端所有资源时会带上这个token,由服务器端来校验这个token的合法性。其具有无状态、适合分布式、扩展性好、性能高和安全性好等优点。
4.2 C-S架构类系统(客户端-服务器)
这类大多以摘要算法和加密算法的为主。
4.2.1 摘要算法
消息摘要算法也被称为散列算法或哈希(Hash)算法。任何消息经过散列函数处理后,都会获得唯一的散列值,这一过程称为 “消息摘要”,其散列值称为 “数字指纹”,如果其数字指纹一致,就说明其消息是一致的。
主流摘要算法有md5和sha系列,sha系列也分为sha1和sha2系列(包含 sha-224、sha-256、sha-384 和 sha-512)。md5与sha系列有啥不区别呢?算法核心过程大同小异,输出的摘要信息位数不同,MD5的摘要的长度是128bit,SHA-1摘要长度160bit。多出32bit意味着什么呢?不同明文的碰撞几率降低了2^32 = 324294967296倍,从而提高了安全性,安全性的提高是以牺牲性能为代价的。
md5把128bit的信息摘要分成A,B,C,D四段(Words),每段32bit,在循环过程中交替运算A,B,C,D,最终组成128bit的摘要结果。
图6 md5计算过程
sha-1算法核心过程大同小异,主要的不同点是把160bit的信息摘要分成了A,B,C,D,E五段。
图7 sha-1计算过程
sha-2系列算法,核心过程更复杂一些,把信息摘要分成了A,B,C,D,E,F,G,H八段。
图8 sha-2计算过程
信息摘要越长,发生碰撞的几率就越低,破解的难度就越大。但同时,耗费的性能和占用的空间也就越高。没有最好,根据实际所需性能和安全性做选择即可。摘要算法由于其单向不可逆性,经常用在验证文件完整性(比如代码的版本比对)和存储系统用户密码口令等场景。
4.2.2 加密算法
加密算法通常分为两大类:“对称式”加密和“非对称式”加密。
对称加密就是加密和解密使用同一个密钥。非对称加密就是加密和解密所使用的不是同一个密钥,通常有两把钥匙,称为“公钥”(Public Key)和“私钥”(Private Key),它们两个必需配对使用,否则不能打开加密文件。
这里的“公钥”是指可以对外公布的,“私钥”则不能,只能由持有人一个人知道。它的优越性就在这里,因为对称式加密加解密公用一套密钥,需要将密钥告诉对方,一旦传输密钥,不管用什么方法都有可能被别人窃听到。而非对称式的加密方法有两个密钥,且其中的“公钥”是可以公开的,即使泄露也只是泄露一部分数据权限,私钥只有持有人自己保存,数据的权限还是得以控制,这样就很好地避免了因密钥的传输安全问题。
4.3 开放平台(open API)
- 安全系数较高的场景(支付、资金下发等)以数字签名为主。
- 安全系数不是很高的场景(查询用户信息等)以accessToken机制为主。具体流程为应用需要基于平台分配的AppId和AppSecret 获取一个accessToken(缓存在本地,需要定期刷新),后续请求接口带上accessToken即可,这样对于安全系数没有那么高的接口不需要每次都走加解密的逻辑,提高性能。
4.3.1 数字签名
数字签名是摘要算法与非对称加密算法的综合应用。客户端(请求端)和服务端(接收端)各自持有一对密钥(这里面有两套密钥),各自把自己的公钥给对方,自己持有私钥。请求方先对报文做摘要获取签名信息,然后使用自己的私钥对摘要信息加密(这个过程称之为加签),接收方使用请求方的公钥进行验签,同理接收方处理完业务响应时也是用自己的私钥加签,数据响应给请求方后,请求方也是使用接收方的公钥进行验签。这种算法在开放平台(尤其以微信、支付宝为代表的支付类平台)的API安全设计中较为广泛使用。
支付开放平台目前主流的两种签名算法:
开放平台签名算法名称 | 标准签名算法名称 | 备注 |
---|---|---|
RSA2 | sha256WithRSA | 先使用sha256做摘要,再使用RSA对摘要做非对称加密(强烈推荐使用),强制要求RSA密钥的长度至少为2048 |
RSA | sha1WithRAS | 先使用sha1做摘要,再使用RSA对摘要做非对称加密(对RSA密钥的长度不限制,推荐使用2048位以上) |
数字签名相当于与在性能和安全性做了trade off,因为摘要结果的数据长度是固定的而且效率高,每次对摘要进行非对称加密,性能的损失得到了控制。 |
五、自身实践经历
5.1 背景介绍
笔者之前一直在金融支付相关业务领域从事研发工作,参与过2c的钱包app应用、2b的资金下发saas系统以及资金下发开放平台等相关系统的API设计与研发工作。下面以资金下发开放平台为例具体谈一下API安全方面的建设。
先说一下何为开放平台:概括来讲就是企业基于自己的业务生态(或者说基于自己的业务sop)进行能力沉淀,以API的形式进行开放,供第三方开发者(个人或者企业)使用(开发者将能力集成到自己的应用之中,达到赋能的目的),这种行为称之为Open API,提供开放API的企业/平台称之为开放平台。
资金下发开放平台是基于薪资下发SOP(标准业务流程)进行能力沉淀,以API的形式对外开放,便于企业将薪资下发的能力集成到自己的应用之中,从而具备下发薪资能力。资金下发开放平台整体采用API GateWay的架构设计。
5.2 API网关整体架构
图9 API GateWay架构设计
API网关采用pipeline(责任链模式)实现网关的核心处理流程,将每个处理逻辑看成一个pipe,每个pipe处理一件事情。这样无论增加处理逻辑还是增加不同协议的服务,仅需新增一个pipe到调度逻辑,想要禁用某个pipe,也能静态或者动态排除它,即可插拔性。客户端请求过来之后通过pipeline实现鉴权、访问控制、流控以及分流等一系列的前置逻辑。底层容器基于netty实现,对外暴露统一采用http协议,请求由容器线程池处理,之后分发到应用线程池异步处理。应用线程池在设计之初考虑不同类型的任务可能会出现耗时不一的情况,所以将任务拆分到不同的线程池以做隔离,提高不同类型任务的并发度,从而提高整体的吞吐。
5.3 选择网关的原因
为什么采用API GateWay的设计呢?核心有三点考虑
1.隔离性
隔离是对企业系统安全的一种保护,由于API是在边界提供给企业组织之间或企业外部进行访问的,因此保证企业系统不受有威胁的访问是API的首要责任。API网关在安全方面实现了将安全访问控制能力从应用程序中剥离至API网关,实现了安全隔离。
2.解耦性
服务的提供者往往希望服务具有始终稳定的服务提供能力,因此往往不希望受到太多的外部功能需求的干扰,但是业务的快速发展决定了业务访问方的需求是多变的,因此通过在服务提供方与服务访问方之间设置一个中间层,通过该层封装不同的业务访问请求并按照统一的服务提供方要求进行转化并访问。通过这样一个中间层,将两个完全不同诉求的双方有效的调和起来,实现解耦。
3.扩展性
从位置与形态上看,API GateWay类似proxy的角色,除了负责请求的接收、路由、响应外,还可以执行诸如流量控制、日志管理、安全控制等。由于业务可能快速变化,如果核心业务功能无法在某些方面快速实现需求,API GateWay可以通过插件化的设计实现自定义功能的快速扩展,来适应业务灵活多变的需求。
5.4 网关在安全方面的建设
应用接入平台时,需要平台给应用分配appId和appSecret,设置安全规则(加密方式),主要是以摘要算法sha256(加盐)和数字签名sha256WithRsa两种鉴权方式,然后分配资源(接口)权限以及接口限流和白名单等相关的配置。然后接入方按照相应的加密规则进行封装报文请求调试接口,进行接入即可。
具体细节:
- ip白名单:ip白名单是指将接口的访问权限对部分ip进行开放,这样就能避免其他ip进行访问攻击。
- 时间戳:请求报文携带时间戳跟服务器当前时间进行对比若超过规定阈值直接被拦截。
- 随机序列:在时间戳有效范围内不允许重复,时间戳+随机序列有效解决了重放问题。
- 接口限流:对服务端资源进行保护。
以sha256WithRsa为例:请求端携带业务字段、appId、随机序列、时间戳等字段做排序,再做sha256摘要计算,然后使用自己的私钥对摘要结果进行Rsa加密得到sign(这个过程称之为加签),将签名结果和其他字段一起封装传输给服务端。服务端接收到后先对时间戳、随机序列、ip进行校验,校验通过后使用请求方的公钥进行验签,验签通过后,进行业务流程,业务处理完毕将响应数据做sha256,再使用私钥对摘要数据做Rsa加密得到sign,和业务报文一起响应给请求方,请求方以同样的方式验签处理数据。整个请求-响应的安全流程机制就是这样。
5.5 小结
API网关不仅仅是针对安全方面的解决方案,更多的是对API治理的一种综合解决方案,集安全性、隔离性、可扩展性等多方面的综合考量,是一种企业级API治理的通用解决方案。
写在最后
本文结合实际业务痛点对系统存在的安全风险漏洞进行了整改,以及落地验证解决问题,继而对行业安全方案进行对比鉴析,并且结合之前的工作经历探讨了一些关于API安全的架构设计。它可能并不全面,或者说并不完全适用所有的情况,但本文的意义更多是起到抛砖引玉的效果,启发大家对API安全的思考,唤醒对API安全的意识。
作者:京东物流 魏晓峰
来源:京东云开发者社区 自猿其说Tech 转载请注明来源