本文主要梳理到公司参与团队后端开发2年多来,总结开发过的项目中遇到的各种安全问题及应对方案。
目前我们后端团队使用的技术主要还是Sprin在这里插入图片描述
gBoot + Mysql + Redis这一套 ,暂未涉及到SpringBoot Cloud,后面内容主要围绕目前团队使用的技术框架来讲解的。
平时大家可能更多注重业务层面的开发(CRUD),然后实现产品的需求就行了,但是却忽略了产品上线后的各种安全问题带来的影响。
下面总结了一些过去发生过的(出现频率高,影响严重的)开发上的问题及带来的严重影响:
安全问题 | 影响 |
---|---|
操作系统、SpringBoot及相关服务jar包等版本漏洞 | 攻击者通过版本漏洞拿到root权限进入服务器为所欲为!中招挖矿病毒,这个大家都有遇到过吧! |
被ddos攻击 | 服务器持续无法访问,影响正常用户的使用 |
弱口令密码 | 出现在登录类的接口、以及redis、mysql等服务的连接信息上 |
短信接口、下载文件消耗类的接口被盗刷 | 这个出现比较多,短信业务被消耗,下载流量持续被别人消耗,带来的是公司钱的损失!! |
充值业务问题 | 这个就比较严重了,涉及到钱的业务开发都要慎重!慎重!再慎重! |
服务器带宽占满等问题 | 同被攻击的常见 |
22端口开放 | 暴力破解,重要的端口应该加上白名单连接!!! |
一款互联网产品开发出来上线后,既然是存在于互联网上的东西,如果设计之初没有考虑开发上的安全设计规范和服务器安全防御方案,那必然是不安全的,记住这点!
不管自研还是模仿同行竞品,在上线后,使用你开发产品的用户多了,说明就越来越有价值了,关注度也越来越高后,就极有可能就会被别人攻击、破解等行为,特别是当老板说这个产品你也给我做出来一个的时候…同行出现竞争者,大家都想吃这块肉,说不定别人就会来搞你,某天周末你正在和朋友在外面嗨皮,突然接到老板电话说服务器宕机赶紧看下,一看有人在ddos攻击…扯远了,扯远了!
总之,你不知道你写的程序哪里突然蹦出个安全漏洞,如果被攻击者发现,就会有安全问题发生的风险!
比如前不久出现一个shiro的安全问题,我们有一个测试项目用的一个基于SpringBoot+Shiro的旧版本框架,该框架没有升级shiro最新版,安全部门的同事测试就发现通过此漏洞拿到了服务器root权限,其漏洞请点击查看
转发链接:Apache Shiro 默认密钥致命令执行漏洞(CVE-2016-4437)
开发者也不必担心在安全设计方面花太多时间,过去2年我和团队在公司开发的后端项目经历了很多安全问题(吃了不少亏换来的经验),所以有了今天的总结,按照所讲的内容一一对应到平日的开发工作里,就能一定程度上减少生产事故的发生!
所以本文主要目的是避免大家开发新的项目重犯以前的错误,把过去常规的一些处理方案整理出来,作为一个平日的开发规范,养成大家在开发方面安全的意识,希望大家在平时开发都应该对每一个接口都有考虑一定的安全处理,对自己每一行代码负责!
啰嗦了这么多,还是有必要给大家说清楚情况,接下来就是正文,下面的内容主要是分享经验及解决问题方案,涉及到技术的不多,部分方案以链接方式转载,具体实施根据各自公司的情况来。
对与能看到这里的小伙伴来说,表示感谢,如果后面有能帮助到你的地方,是我莫大的荣幸,有错误或者建议也请联系本人,及时沟通一起进步!
接下来主要从2个方面来规范后端开发安全:
前提:对于XX后台管理系统,后台的相关接口除了登录注册等接口,肯定是需要登陆鉴权后才能访问的,这里主要针对于一些提供给第三方使用的开放接口,直接公开就能访问的接口需要做的鉴权!
就比如,大家应该对微信登录、短信接口、支付宝支付等其他第三方服务有对接过吧,没有对接过的自行百度!!!看下别人写的对接文档,是不是接口的参数都有什么apiId, apiSecret ,MD5加密校验啥的,对接多了就清楚明白了,使用别人的技术也要去思考为什么要这么设计嘛,一是区分渠道(谁来请求的),二就是对应的安全处理。
网上有很多优秀的博主发过方案,这里转发推荐:
转载链接1:开放API接口签名验证,让你的接口从此不再裸奔
转载链接2:API安全接口安全设计
最好就是公司有一个统一的鉴权中心服务,所有的接口鉴权都走这个服务,目前我们是单个项目按照上面的方式写的鉴权,我正在做这个事情,等后面我们搭建好了一个这样的统一鉴权中心发出来总结给大家分享一下!
不知道大家平日开发的接口有没有做并发处理?特别是一些新增,更新业务的接口,说不定你写的接口一个简单的并发测试就能看出一些问题。
我们设计的接口并不需要像淘宝、京东那样亿级高并发,做好一个符合实际公司业务接口性能需求就行了(根据公司业务来定),要对症下药。
这里说的限流其实和并发相关了,对于高并发的技术讨论不在这里展开讨论,这个东西太大,我们直说场景和处理方案:
简单来说就是正常请求量放大10倍甚至更多后,你的系统如何应对?
换句话说,正常测试的情况是你单台服务器最高承受300的并发量,如果突然某个时间并发量3000,6000,1万 又如何应对?
这里举个简单例子便于理解:
假如一个登录接口,测试在指定X核XG X带宽 环境下,300并发量同时登录没问题的,突然3000并发,服务器就宕机了。
单台物理机的性能指标总会有一个阈值,但为了保证服务的稳定性,我们可以怎么做呢:接口限流是一个方案。
在应对突然增高的访问,我们可以拒绝掉部分请求,保证服务器的稳定性,这个其实和设计一个抢购秒杀程序差不多的原理。对于恶意的请求量,也是同样的道理,但也是一把双刃剑,缺点是正常用户的请求也会被过滤掉。
接口限流的对象:
目前我们项目中在用的2个的方案:
参考转载链接: https://blog.csdn.net/qq_22167989/article/details/107341080
参考转载链接: https://www.cnblogs.com/xinzhao/p/11465297.html?utm_source=tuicool&utm_medium=referral
如果你有更好的方案可以评论推荐一下!
一个例子:
谈到充值业务的开发,我就想起以前遇到一个初级程序员同事(真的不是我)犯过的一个典型错:
业务功能是:后台有个充值按钮,选择单个用户后点击充值按钮,输入金额就可以给该用户增加金额,同时本人减少相应金额。
看似一个很简单的功能,其实就是一个银行取钱的例子,假设我的余额是200块,正常流程就是:我取了100块,剩下100块没毛病吧,取钱的时候就有一个接口处理业务逻辑,结果这个接口没做任何处理,没加锁,没事务,造成的后果就是,我在0.11111 毫秒内,狂点了100次取钱,然后我钞票机给我了1000块,我的余额还是100块!要是银行真这么设计早就倒闭了!
就是这个场景,发生在实际公司业务中,被别人撸了羊毛,好在有日志操作记录把这个用户相关操作记录全部给他退回了,最后修复了这个充值接口的bug,加锁,加事务,限流(不能被狂点)
那他也受到了相应的惩罚,罚了款!
这里再举例一个反例,不要这么设计:比如 /api/recharge?userId=100&amount=100, 请求访问后就可以给用户id为100的用户充值100块,相信大家不会这么去设计接口,真这么设计怕是要着锤的,这么看也太不专业了,我觉得以后面试人可以增加这个充值接口方案设计题,真有人这么来搞就可以下一个了。
总结:
回归充值业务的设计,作为负责这块写代码的你可得打起十二分精神,特别是设计到钱的问题,头脑应该马上有一个安全意识,结合上面(1)(2)点的接口安全设计方案,我们也不说啥高大上的设计,该加锁的加,加事务,即使你的代码冗余,也要安全 > 性能!!!当然我不希望你做团队写代码最笨的人,要不断去优化自己的代码,去学习别人优秀的支付架构设计方案!(这个话也是对自己说的)
此外充值一定要有对应的日志记录,出现问题也是辅助分析的地方,写到这里,我觉得自己也应该提升下这块业务的开发方法并总结出来,学习使人进步!
大家在公司做项目,如果涉及到短信业务,文件上传,这种场景,你是如何设计的?
我先说下最原始的版本1:
XX系统对外有一个手机注册页面,正常用户注册需要请求接口发送手机验证码,假如这个发送验证码接口张三是这么设计的: /api/getVerificationCodeByPhone?phone=1234567890,
张三也知道,对手机号码做了格式校验,就没其他过多的设计了,看到这里你就可能就笑了,突然有一天,客户反馈充值充不上了,老板赶紧打电话让正在度假的张三看看怎么回事,张三看见服务器的短信接口报错余额不足了, 结果一看日志,一大堆获取验证码的接口日志,一想,肯定是别人盗刷接口了。
那对于短信接口设计:
短信接口方案只是一个例子,其他类似的需要充值才能使用的接口,比如
谷歌翻译接口
百度地图API
邮箱发送验证接口
等等业务中会用到的第三方接口也都应该做类似的处理!!!
这里说的对象存储指的是使用的 阿里云对象存储OSS 或者 华为云对象存储OBS 或者其他平台的对象存储,各平台使用方式都差不多,用过的小伙伴应该清楚,没用过的小伙伴可以理解为一个独立的文件服务器,和你部署的SpringBoot 服务器隔离开,文件的上传下载都走这个独立的文件服务器,不要一台服务器集中了所有服务(nginx,springboot,redis,mysql,文件存储…)
为什么要这么设计呢?这里我推荐一篇好朋友写的博客: 大型网站架构演化发展历程
目前我们项目的架构类似这样子(nginx 集群部署):
因为公司项目的业务会有大量的文件上传下载,所有服务器都上了云,对象存储这个使用也很简单,有对应的各种语言的SDK接入,我们可以通过API 上传和下载文件。
这里直接说下使用中出现的问题:
问题1:秘钥保存在客户端
最开始有个项目,最高权限的秘钥保存在客户端上,这无疑是最危险的做法,而且客户端已经对外公开,有一定逆向能力的程序员通过反编译APK即可拿到这个秘钥,也等于拿到了我们文件服务器所有权限,
可以通过秘钥遍历获取所有文件,或者新增删除之类的操作,非常危险,随后发现这个问题立即禁用这个key,重新讨论设计文件存储方案。
问题2:桶的文件下载链接公开,被别人盗刷流量
创建对象存储桶的时候有一个选项,桶策略:公开还是私有,以下图华为云为例
我们创建一个桶后如果是公开的,那么上传的文件下载链接可以直接访问,这里存在一个风险就是华为云的下载流量是按使用计费的,如果有对外公开的文件,恶意攻击者拿到公开文件下载链接就可以写个循环下载脚本,恶意消耗你的流量,账号上面的余额很快被吃完。
围绕这个风险,我们说下做法:
尽可能的不要有公开的文件下载链接,除非你钱多当我没说。
桶私有的情况下,官网有相应的API,可以根据文件路径生成一个临时上传、下载url的方案给客户端:
请参考官方文档链接: https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0901.html
基于此方案,在服务端设计一个接口返回临时url,也要结合1.1 接口安全设计,加上鉴权和频率,
鉴权的对象及频率限制有很多方案:
总之,前面围绕的设计思路核心都是鉴权 和限制请求频率,要学会灵活运用。
后端开发工作中,我们常用技术有: SpringBoot、redis、mysql、shiro、nginx等,这里不一一列举,在文本开头有提到一个 shiro安全问题的例子,就是一个典型,得益与我们有优秀的安全工程师,他们可以分析你所开的应用、使用的框架及版本有什么问题,如果你们没有专门的安全部门,也可以自己网上看下相关框架版本漏洞,这里整理几个会经常公布互联网安全漏洞的网站:
华为: https://www.huaweicloud.com/notice.html
阿里云: https://help.aliyun.com/document_detail/60797.html
如果你现在使用的框架版本出现了对应的问题,就应该及时升级,同时升级注意各个组件的兼容性,避免出现了问题再来处理,造成了严重后果,就后悔莫及了!
这里主要说明一下比如springboot 的yml配置文件信息,像比如连接数据库,连接redis的账号密码建议应该加密保存。
其次公司都应该有自己内网的git服务器吧,千万不要把公司项目上传到公网公开访问,否则你面临法律方面的危险!
相关加密方案请参照: 基于spring boot框架的配置信息加密方法总结 ,建议使用其文档描述的4.2.1 命令行加密(推荐)方案。
这里的秘钥指的是比如对象存储的秘钥,以及系统接口加解密的公钥之类的重要信息。
目前我们项目接口有做参数加密,服务端基于内存保存秘钥,具体方案设计到项目细节这里不展开描述,大家如果好的方案保存一些秘钥可以分享一下!
我相信大家都自己搭建过mysql redis等服务,往往我们自己搭建测试的时候,跟着demo一顿操作,密码123456的这种就用上了,然后你的服务器突然某天就中挖矿病毒了,或者mysql数据被清空,你有遇到吗?
这种密码程序很容易暴力破解出来,中招服务器就完了,大多数出现问题的服务器都首先检查下你的密码问题,
不知道该设置啥密码,就使用一些密码生成器之类的:https://1password.com/zh-cn/password-generator/
自己用Java代码写一个最安全!下面整理一些需要注意的地方,提高你的密码强度:
所有云服务重要端口都应该加上白名单,特别是22端口,只能是你所在办公IP才能访问!
什么是ddos攻击,网上有很多资料,这里转载一篇,后端开发都应该了解一下,点击了解: DDOS攻击原理
简述就是:大规模流量(几百G或者更高)涌入服务器,导致服务器处理不过来,只要攻击不停止,服务器就一直处于"无响应状态",部署的web服务也无法正常访问,直接影响项目!
公司的项目只要是部署生产环境上线后,基本上都遭遇了ddos攻击(太难了)。
最简单、最有效的方法就是购买并部署高防服务器应对,缺点是需要加钱。这个时候不是去想着怎么优化代码了,需要从外部去解决,市面上有很多高防服务器厂家,这里不做广告推荐,有被攻击的小伙伴不知道怎么做可以找我沟通一下。
高防服务器就等于服务器的一个盾牌,所有的请求先到高防服务器,由高防服务器解析是好是坏,再转发的我们的源站服务器来。
使用高防后注意的问题:
当然,配置了高防服务器不代表就100%无敌安全了,一山更比一山高,攻击流量大于你的防御流量你也防不住,需要不断去优化策略应对。
转载链接: 常见六大Web安全攻防解析
除了ddos攻击,日常的后台接口服务器也会有其他不安全因素,如果使用公司提供的一套基础框架模版(已经包含处理了上述问题风险)去开发,就不用担心这些问题的发生,毕竟我们最终还是得专注于业务开发呀!
结合第(2)点被ddos攻击的情况,原因是因为你的服务器ip暴露了,攻击者直接攻击源服务器,加上高防后,使用域名的方式,不要暴露你的源服务器IP。
总结:项目正式上线前,应该提前考虑好被ddos攻击的风险及应对措施,提前准备好高防服务器部署,保证后续服务器的稳定运行。
这里主要针对于初创的中小公司,开发环境各方面都不太规范,比如使用 外网Gitlab,码云 或者GitHub来管理研发项目,大公司应该都有完善的安全的研发环境,像比如华为,阿里,腾讯的朋友,特别是华为的员工,听说基于内网开发,百度还得用手机这种情况大家有没有听说过呢?
为什么要用内网搭建服务呢?前面也说了服务会有各种漏洞,会有被入侵风险,比如Gitlab官方就随时在更新,我们团队目前就是内网搭建的Gitlab,代码是整个研发团队、公司最重要的资产;
内网环境下一定程度上减少了被泄露的风险,但是管理者也要规范团队每个开发者的日常行为规范(人为因素)。
下面列出内网搭建的服务及使用地方:
内网搭建 | 使用范围 |
---|---|
Gitlab | 管理项目代码仓库 |
禅道 | 项目管理 |
由于Windows操作系统其普及性和软件适配性(相比Linux),大多数中小公司研发团队可能都会基于Windows进行开发,但是Windows太"成熟"了,开发成本低,一不小心点错、下错东西,打开就是各种病毒、木马、广告,电脑中毒不说,同时又间接影响内网环境。
所以目前我们团队使用的操作系统是Ubuntu20.04,一样的有图形化界面,实践1年多了,前后端开发都不会受影响,和Windows一样,强烈建议大家还在用Windows系统进行开发的小伙伴换成 ubuntu或者mac,当然mac需要苹果笔记本,成本比较高。