由一次安全扫描引发的思考:如何保障-API-接口的安全性?(1)
这里要注意的是客户端的时间和服务端的时间基本上是不可能一致的,加上请求本省在网络中传输还有耗时,所以时间限制的阀值不能设定的太小,防止合法的请求无法访问。
我还是拿上面的登录举例子,到这一步,我们的请求数据会变成下面这个样子:
{
“name”: “test”,
“password”: “123”,
“timestamp”: 1590334946000,
“sign”: “098f6bcd4621d373cade4e832627b4f6”
} 5. AppID很多时候,我们一个 API 接口可能并不是只会有一个客户端进行调用,可能调用方会有非常多,我们的服务端为了验证合法的调用用户,可以添加一个 AppID 。
想要调用我们的 API 接口,必须通过线下的方式像我申请一个 AppID ,只有当这个 AppID 开通后,才能对我的接口进行合法的访问,在进行接口访问的时候,这个 AppID 需要添加到请求参数中,与其他数据一起提交。
到了这一步,我们上面那个登录接口的传入参数就变成了下面这样:
{
“appid”: “geekdigging”,
“name”: “test”,
“password”: “123”,
“timestamp”: 1590334946,
“sign”: “098f6bcd4621d373cade4e832627b4f6”
} 6. 参数整体加密我们上面对请求的参数进行了一系列的处理,总体思想是防止第三方进行抓包和破解,但是如果我不是第三方呢,比如我就在浏览器的 network 中进行抓包,这个请求中的数据我就能看的清清楚楚明明白白,攻击者可以先通过正规的途径进行访问,当分析清楚我们的套路后再对请求进行伪造,开始攻击,这时我们前面的努力好像就都白费了。
不要说什么没有人会这么做,我就举一个例子,支付宝网页端的登录接口,如果能搞清楚其中请求的发送规则,攻击者就可以使用买来的用户数据库,进行批量撞库测试,通过请求响应的结果就可以验证一批的支付宝的账号密码(当然不会有这么简单哈,我只是举例子)。
我们接下来还能再对请求做一次整体加密,现在主流的加密方式有对称加密和不对称加密两种。
对称加密:对称密钥在加密和解密的过程中使用的密钥是相同的,常见的对称加密算法有 DES , AES , RC4 , Rabbit , TrIPleDes 等等。优点是计算速度快,缺点是在数据传送前,发送方和接收方必须商定好秘钥,然后使双方都能保存好秘钥,如果一方的秘钥被泄露,那么加密信息也就不安全了。
不对称加密:服务端会生成一对密钥,私钥存放在服务器端,公钥可以发布给任何人使用。优点就是比起对称加密更加安全,但是加解密的速度比对称加密慢太多了。广泛使用的是 RSA 算法。
对上面我们提交的数据做一次 DES 加密,密钥使用 123456 ,我们可以得到这样一个结果:
U2FsdGVkX18D+FiHsounFbttTFV8EToywxEHZcAEPkQpfwJqaMC5ssOZvf3JJQdB
/b6M/zSJdAwNg6Jr8NGUGuaSyJrJx7G4KXlGBaIXIbkTn2RT2GL4NPrd8oPJDCMk
y0yktsIWxVQP2hHbIckweEAdzRlcHvDn/0qa7zr0e1NfqY5IDDxWlSUKdwIbVC0o
mIaD/dpTBm0=然后我们把这个字符串放到请求中进行请求,我们刚才的登录请求就会变成这样:
相信这样一来,超过 99% 的攻击者看到 network 中这样的抓包请求都会放弃,但是还剩下 1% 的人会打开 Chrome 提供的开发者工具进行一行一行的 debug ,针对这部分人,我们下面在客户端的段落里再聊如何对付他们。
7. 限流很多时候,在某些并发比较高的场景下,基于对业务系统的保护,我们需要对请求访问速率进行限制,防止访问速率过高,把业务系统撑爆掉。
尤其是一些对外的接口,给客户或者供应商使用的接口,因为调用方我们自己无法控制,天知道对方的代码会怎么写。
我曾经见过供应商把我们提供的修改数据的接口拿来当做批量接口跑批,每天晚上都能把那个服务跑挂掉,后来直到我们去问,供应商他们才说每天晚上会用这个接口做上千万的数据同步,我也是醉了。
服务端限流的算法常见的有这么几种:令牌桶限流、漏桶限流、计数器限流。
令牌桶限流:令牌桶算法的原理是系统以一定速率向桶中放入令牌,填满了就丢弃令牌;请求来时会先从桶中取出令牌,如果能取到令牌,则可以继续完成请求,否则等待或者拒绝服务;令牌桶允许一定程度突发流量,只要有令牌就可以处理,支持一次拿多个令牌。
漏桶限流:漏桶算法的原理是按照固定常量速率流出请求,流入请求速率任意,当请求数超过桶的容量时,新的请求等待或者拒绝服务;可以看出漏桶算法可以强制限制数据的传输速度。
计数器限流:计数器是一种比较简单粗暴的算法,主要用来限制总并发数,比如数据库连接池、线程池、秒杀的并发数;计数器限流只要一定时间内的总请求数超过设定的阀值则进行限流。
实现方面来讲, Guava 提供了 RateLimiter 工具类是基于基于令牌桶算法,有需要的同学可以自己度娘一下。
8. 黑名单黑名单机制已经有点风控的概念了,我们可以对非法操作进行定义。
比如记录每个 AppID 的访问频次,如果在 30 分钟内,发生了 5 次或者以上的超频访问并且超出了 10 倍以上的访问量,这时可以将这个 AppID 放入黑名单中, 24 小时以后或者调用方线下联系才能将这个 AppID 取出。
再比如记录 AppID 超时访问次数,正常来讲,超时访问不会频繁发生,如果在某个时间段内,大量的出现超时访问,这个 AppID 一定存在问题,也可以将其先放入黑名单中让它冷静冷静。
黑名单实际上更多的是应用在业务层面,比如大家可能碰到过的拼爹爹的风控,直接把账户扔到黑名单里面,禁止这个账户对某些补贴商品的下单。
客户端
在当今的互联网时代,网页和 APP 成为了主流的信息载体。
其中 APP 是可以使用一些加固技术对 APP 进行加固,防止别人进行暴力破解。
而网页就比较困难了,网页的动态都是依靠 JavaScrIPt 来完成的,逻辑是依赖于 JavaScrIPt 来实现的,而 JavaScrIPt 又有下面的特点:
JavaScrIPt 代码运行于客户端,也就是它必须要在用户浏览器端加载并运行。JavaScrIPt 代码是公开透明的,也就是说浏览器可以直接获取到正在运行的 JavaScrIPt 的源码。基于这两点,导致了 JavaScrIPt 代码是不安全的,任何人都可以读取、分析、盗用、篡改 JavaScrIPt 代码。
所以说, JavaScrIPt 如果不进行一些处理,不管使用了如何高超的加解密方案,在被人找到其中的逻辑后,被模拟或者复制将变得在所难免。
前端 JavaScrIPt 常见的加固方案有这么几种:压缩、混淆、加密 。
1. 压缩代码压缩,就是去除 JavaScrIPt 代码中不必要的空格、换行等内容,把一些可能公用的代码进行处理实现共享,最后输出的结果都压缩为一行或者几行内容,代码可读性变得很差,同时也能提高网站加载速度,就想下面这样:
这个是我从百度的页面上随便找了一个 js 截出来。
如果是单纯从去除空行空格这个角度上来对代码进行压缩,其实几乎是没有任何防护作用的,因为这种压缩方式仅仅是降低了代码的直接可读性。
我们可以通过各种工具对代码进行格式化,包括 Chrome 浏览器本身就提供了这个功能。
目前主流的前端技术都会使用 Webpack 进行打包,Webpack 会对源代码进行编译和压缩,输出几个打包好的 JavaScrIPt 文件,其中我们可以看到输出的 JavaScrIPt 文件名带有一些不规则字符串,同时文件内容可能只有几行内容,变量名都是一些简单字母表示。
这其中就包含 JavaScrIPt 压缩技术,比如一些公共的库输出成 bundle 文件,一些调用逻辑压缩和转义成几行代码,这些都属于 JavaScrIPt 压缩。另外其中也包含了一些很基础的 JavaScrIPt 混淆技术,比如把变量名、方法名替换成一些简单字符,降低代码可读性。
整体上来讲, JavaScrIPt 压缩术只能在很小的程度上起到防护作用,要想真正提高防护效果还得依靠 JavaScrIPt 混淆和加密技术。
2. 混淆JavaScrIPt 混淆是完全是在 JavaScrIPt 上面进行的处理,它的目的就是使得 JavaScrIPt 变得难以阅读和分析,大大降低代码可读性,是一种很实用的 JavaScrIPt 保护方案。
JavaScrIPt 混淆器大致有两种:
通过正则替换实现的混淆器通过语法树替换实现的混淆器第一种实现成本低,但是效果也一般,适合对混淆要求不高的场景。第二种实现成本较高,但是更灵活,而且更安全,更适合对抗场景。
通过语法树替换实现的混淆器,这种混淆方式的实现有点复杂了,我这里就不展开去聊了,有兴趣的同学可以参考这篇文章:https://www.zhihu.com/question/47047191/answer/121013968 。
针对修改语法树进行混淆的方式,目前有一家做的比较好并且提供商业服务的是 jscrambler ,他们的官网地址:https://jscrambler.com/ 。
总之,以上方案都是 JavaScrIPt 混淆的实现方式,可以在不同程度上保护 JavaScrIPt 代码。
在一般的场景中,第一种混淆方式足够我们使用,现在 JavaScrIPt 混淆主流的实现是 javascrIPt-obfuscator 这个库,利用它我们可以非常方便地实现页面的混淆,它与 Webpack 结合起来,最终可以输出压缩和混淆后的 JavaScrIPt 代码,使得可读性大大降低,难以逆向。
3. 加密不同于 JavaScrIPt 混淆技术,JavaScrIPt 加密技术可以说是对 JavaScrIPt 混淆技术防护的进一步升级,其基本思路是将一些核心逻辑使用诸如 C/C++ 语言来编写,并通过 JavaScrIPt 调用执行,从而起到二进制级别的防护作用。
其加密的方式现在有 EmscrIPten 和 WebAssembly 等,其中后者越来越成为主流。
感兴趣的同学可以自行度娘了解下。
小结
上面介绍了这么多,只是为了我们的程序能够更加安全稳定的运行,减少因为攻击而产生的损失(加班)。
很多内容都是来自度娘后进行信息整理,希望各位能够善用搜索引擎这个工具。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加VX:vIP204888 (备注网络安全获取)
给大家的福利零基础入门
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
因篇幅有限,仅展示部分资料
绿盟护网行动
还有大家最喜欢的黑客技术
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
)
所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长! [外链图片转存中…(img-gNpJl2Ej-1713079244729)]
Ongwu博客 版权声明:以上内容未经允许不得转载!授权事宜或对内容有异议或投诉,请联系站长,将尽快回复您,谢谢合作!