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