
背景:
设计一个 http 接口,给客户端访问,但是这个接口会访问 redis 和 mysql,所以这个接口如果被别人知道,恶意攻击,可能会导致 redis 或 mysql 炸掉,所以有没有什么可行性的方案? 我的解决方法:
后端和前端约定一个 token,该接口是 post 方法请求,客户端每次请求都会在 form 中携带这个 token,后端通过比较这个 token,如果一致则执行业务代码,反之返回。因为 web 服务器前有一层 slb,ssl/tls 加在 slb 上,所以这样中间人应该获取不到这个 token 吧? 这样安全吗?比如说,攻击人能从 app 程序二进制获取 token? 或者还有没有别的方案?
1 VVVV7 Nov 24, 2020 1. sign 签名 + time 时间戳 2. IP 限流 |
4 twg OP 额..其实我想问的重点是,我想怎么区别这个客户端是我们 app 用户还是恶意用户? |
7 locoz Nov 24, 2020 via Android 如果你这个接口是公开的,别人在你的网站或者 app 上抓个包就能看到,并且接口返回的内容对用户来说有实际意义的话,那就老老实实加风控,你自己整的那些花里胡哨的没啥意义。 |
8 locoz Nov 24, 2020 via Android #7 加风控 -> 加风控厂商的风控产品 |
10 zxCoder Nov 24, 2020 限制请求频率? |
11 imdong Nov 24, 2020 接口签名,客户端将密钥保护好,没有更好的办法。 最近开项目,就遇到同样的问题我的做法是这样的(也是比较通用的做法): 具体思路就是,客户端与服务端约定一个密钥(密码串),然后将请求的 GET POST 数据与客户端版本,当前时间戳,唯一随机数打包成一个字符串后用密钥签名( RSA Sign or hash ),放进 header 头传回服务器。 服务器根据客户端版本选择密钥对数据进行签核对时间,并检查 Redis 是否存在此唯一随机数,通过就将 唯一随机数存至 Redis,一分钟后过期。 只要保证客户端这边没有被反编译,就基本安全(没有绝对的安全,涉及到客户端的,一定有可能被破解) |
12 xuanbg Nov 24, 2020 限流,可以根据来源 IP 进行访问限制,譬如每秒只允许同一 IP 请求 1 次,超过的就丢掉。问题是会误杀,因为很多局域网的用户对外都是同一个 IP 。 |
15 soulmt Nov 24, 2020 参照微信小程序 login,设计一次性 token 用完过期, token 用对称加密即可,除非反编译源码,否则这个 token 可以解决这个问题。 |
16 Jooooooooo Nov 24, 2020 1l 的方法基本就是通用的 约定好加密方法然后每次请求带上时间戳和加密数据, 用事先交换好的密钥去加密 请求参数+时间戳, 得到的数据和服务器上计算对比, 不一致直接返回错误 如果你想问 4l 这种风控的问题, 就没那么简单了 限制访问可以用限流+拉黑这种方法 |
17 qiayue PRO @twg 上面这些大哥说的签名是很常用的方式,可以参考微信的这个文档 https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html |
18 locoz Nov 24, 2020 @twg #9 当然能看到,抓包、反编译、Hook 随便一个操作就能看到了。加签名、IP 限流之类的也没啥用的,一般做开发的人弄出来的防护都是跟纸糊的一样,随便就能捅破。所以如果你的这个接口想要确保绝大多数情况下的安全,那就老老实实用专业做这块的人弄的服务...如果你感觉没必要的话,那就说明这个接口没有重要到那种程度,随便加个限流就好了。 |
19 opengps Nov 24, 2020 用 redis 做个访问频率限流,或者幂等性处理从缓存里直接返回同样的数据 |
20 twg OP |
22 zhiguang Nov 24, 2020 如果是私有接口弄个 ssl 双向认证 |
23 zjsxwc Nov 24, 2020 每隔一段时间给你客户一个你的证书与私钥, 参考农行的 K 宝 |
24 meshell Nov 24, 2020 app 签名方式 防不住大佬的。就像 #13 说得一样,加一些风控吧,验证码这些 增加破解难道 . |
25 Macv1994 Nov 24, 2020 谷歌翻译的 secret 字段大佬都能给你破译出来 哈哈哈 不过现在好像没有用了 |
26 shellic Nov 24, 2020 Nginx 可以限制请求频率 |
27 murmur Nov 24, 2020 首先要注册,实名制使用接口,然后在注册鉴权这部分拦截,微信有 token 但是 token 也是人获取的可以查到是谁 |
28 gadsavesme Nov 24, 2020 限流呗,如果是恶意攻击前端加密也不靠谱的。 |
29 AkideLiu Nov 24, 2020 via iPhone 如果简简单单就能解决,那些做 cyber security 的早去开滴滴了 |
30 yscg Nov 24, 2020 看看重放攻击的解决方案 |
31 polymerdg Nov 24, 2020 对称加密签名 |
32 polymerdg Nov 24, 2020 约定大于配置 |
33 tqrj Nov 24, 2020 没有绝对的安全 如果是没有登录的接口:可以根据 IP 去限制并发量这是最简单的 然后就是前端 JS 生成 token 后端进行效验具体细节 自己研究 参考 国外 CloudFlare 俗称五秒 cdn 最开始几代很容易破解其实。目前第三代还是有一定难度 JS 有混淆 vm 加密之类的解密很耗精力 登录之后的接口:其实可以直接 redis 限制并发为 1 这样?再配合 nginx 完成一些基础的限制 上面都是我瞎想的没有实践经验 |
34 Koral Nov 24, 2020 https://docs.konghq.com/hub/kong-inc/rate-limiting/ 看下这个呢?不知道满不满足需求 |
35 LLaMA2 Nov 25, 2020 假定你的接口叫 api,GET 请求, 且传递的参数是 data=abc 。 为了防止恶意重放攻击,可以实现如下: api?data=abc&time=时间戳&code=1000&hash=xxxx 其中 hash 规则是 md5(abc + 时间戳 + 干扰码) 时间戳和 time 的保持一致,为了后端做超时检测, 干扰码和 code=1000 存在对应关系。 即你有一张表,事先生成了一堆序号和干扰码,干扰码对应的序号只有你和 APP 知晓,保证不能泄漏(实际上坏人需要花时间破解) 你每次收到消息后按照同样的方法计算 hash 比较,发现 hash 比对不上,就说明数据被篡改,时间戳超时可能是重放。服务器就直接丢弃,返回错误给前端 |
36 aawei Nov 25, 2020 via iPhone 验证码 |