没搞懂 HTTP 请求的安全验证,求指导!

2022-06-02 17:02:24 +08:00
 Eyon

比如请求 https://abc.com/api ,服务器那边可能需要一个验证,比如要求 headers.Authorization === "abcdefg",

那么,也就是说我在请求是,必须在 headers 中添加 Authorization = 'abcdefg'就可以成功请求,这个逻辑没错吧?

问题是:

比如自己做个网站,浏览器打开首页,就需要从服务器提供的 API 中获取一些数据以供后续服务,API 那边定义是要求 headers.Authorization === 'abcdefg',所以前端写 axios 请求的时候,就加上了 authorization="abcdefg"这个请求,正常工作没有问题。可是,由于在浏览器中的请求标头中可以看到 Authorization:abcdefg 这个明文信息,任何人都可以看到,那不就是任何人都可以通过其他任何方式(比如 postman)来请求这个数据了吗?

当然,你可能会说加密。即便吧 abcdefg 加密成任何形式的密钥,但始终能在请求标头中看到加密后的密钥,用这个密钥发送请求依然可以成功,意义何在呢?

当然,这个问题一定是我自己哪里逻辑没搞清楚。求解答!

4071 次点击
所在节点    问与答
81 条回复
virusdefender
2022-06-02 17:04:12 +08:00
你自己再写一个后端,来中转这个请求
Eyon
2022-06-02 17:06:38 +08:00
@virusdefender 还是没搞懂逻辑,中转的意义又何在呢?任何人不是一样可以通过 postman 带上这个 Authorization 来请求数据吗?
polaa
2022-06-02 17:10:09 +08:00
啥叫任何人 …. mitm 原理了解一下
dcty
2022-06-02 17:14:24 +08:00
如果你是 HTTPS ,header 就是加密的,只有你本地才能看到的,不存在任何人都可以看到,除非 mitm 。
gkirito
2022-06-02 17:15:35 +08:00
建议看看 OAuth 等类似认证逻辑,一般你能拿到这个 Authorization 后面的 token 是要先进行正常的账号密码登录,才能获获取到这个 token ,而且这个 token 是带签名和过期,即便你在使用过程中,一不小心被别人窃取了这个 token ,也是可以直接取消这个 token ,出现这个 Authorization 是为了简化登录认证过程,只需要第一次登录,服务端下发一个带签名可过期 token 这个 token 的获取,是要用户登录成功后端才返回,并且前端要保证返回 token 使用过程中不会乱发到别的网站
dcty
2022-06-02 17:19:03 +08:00
其实,OP 的意思应该是不想自己的 API 能够被爬虫或者第三方客户端直接利用了吧。
不提供网页版,客户端做 SSL Pinning 。
Eyon
2022-06-02 17:19:18 +08:00
https://imgur.com/a/IK7fIOh

比如这个,这个不是就可以看到吗?
然后拿着这个 authorization 不是就可以去请求这个接口中的数据吗?
cheng6563
2022-06-02 17:21:25 +08:00
就是设计如此,HTTPS 防网络连接攻击,但不防用户自己从浏览器拷贝 Token 。

你看百度网盘的第三方 cli 客户端,就是要用户手动从已登录的浏览器里面扣 cookie 使用。

有一些混淆,HASH 之类的方法可以进一步保护 Token ,但不是常规方案。
IvanLi127
2022-06-02 17:21:42 +08:00
大概可以类比为,你如果把口令说出去了,大家都知道了。在你把口令泄露出去之前,这个口令有意义吗?
cheneydog
2022-06-02 17:22:04 +08:00
只有客户端和服务端能看到吧,中间人看不到的。
中间人要想看到这个值,就得在创建 https 链接阶段开始攻击。
Eyon
2022-06-02 17:22:05 +08:00
@gkirito 没有设计用户系统,所以我就不知道这个东西的意义在哪里。
FanError
2022-06-02 17:23:02 +08:00
@Eyon 你自己看到,不代表别人能看到呀,就好比,我现在想知道你的 authorization ,我去哪里看,跑到你电脑上面来看吗?
ryd994
2022-06-02 17:23:08 +08:00
1. 如果你想挡住非浏览器用户,你应该用反爬技术 /图灵测试。鉴权的目的是确认请求来源掌握这个密码。而不是确认请求来源是特定真人。
2. HTTP basic/digest authentication 一般配合 HTTPS 使用。脱离 HTTPS/CA 的鉴权很容易被中间人。
3. “即便吧 abcdefg 加密成任何形式的密钥,但始终能在请求标头中看到加密后的密钥,用这个密钥发送请求依然可以成功”
这就是我反对用户侧密码 hash 代替 HTTPS 的原因。用户侧密码 hash 只不过是把 hash 结果变成了实质上的密码。
4. 你这个需求,一般通过限时 /限次数的 token 控制。网页中嵌入 token 。API 请求时带上 token 。就算有人能从网页源码中找到 token ,token 也会过期被服务器拒绝。
Eyon
2022-06-02 17:25:30 +08:00
@cheneydog 关键是客户端的用户也有可能拿着我这个“abcdefg”去用 postman 请求啊,因为他浏览器能看到。

这个帖子没有讨论中间人攻击什么的。
Eyon
2022-06-02 17:27:15 +08:00
@ryd994 我不过是想挡住浏览器用户而已。也就是说用户请求我的页面,页面可以获取这一份数据。但是如果他拿到 postman 中,就不能获取我这个数据。
Eyon
2022-06-02 17:31:04 +08:00
@ryd994 通过限时限次,在网页中嵌入 token 的流程是一个什么样的流程呢?

我目前是想当然的认为:

所有的用户打开浏览器首页,都发送 auth:abcdefg ,服务器端判断确实有 auth:abcdefg 这个字段,就放行数据。也就是:

在 index.html 的 js 中写死‘abcdefg’这个 auth————————>服务器端接收,给数据。

当然,这个流程一定是不对的,应该是一个什么样的流程呢?
huxins
2022-06-02 17:34:40 +08:00
楼主解决问题的方向错了,防止使用者通过非浏览器方式调用,可以动态生成 sign 等。但也只是加大破解难度,做不到完全禁止。
攻和防,只是成本问题。
你只要想在浏览器中展现数据,用户就一定可以在其他地方(如 postman )中,获取数据。
常用解决方案:5 秒盾,各种验证码。
cctrv
2022-06-02 17:39:31 +08:00
1. 想拒絕用戶從 PostMan 之類的工具取得數據,是不存在的方案。
2. 要認識清楚任何客戶端模式( Web 、App )都無法保證數據只有一種方式獲得。
3. 如果你真的那麼想保護你的數據,那麼只有一條路給你,開發對應的硬件,獨立的網絡通道,讓外人無法從任何方式監視到你的數據流動,那麼才可以保護你的數據。
Eyon
2022-06-02 17:39:53 +08:00
@huxins 比如,我做个图书网站,里面有 10000 本书。
在浏览器中,我用 get_books_list 这个请求,得到这 10000 本书的 array ,然后在浏览器中展现出来供用户浏览。

但是,用户也可以直接在 postman 中,用上他在浏览器中看到的 auth token ,直接在 postman 中请求 get_books_list 这个接口,得到我这 10000 本书的 json 数据,包括价格、图片、isbn 等等,这不是很尴尬吗?

难道,本来就是这样的?
leo108
2022-06-02 17:42:01 +08:00
太长不看版:

楼主:我想把一个钉子钉进墙里,但是🪛根本就没法做到,那🪛存在的意义是啥?

因为你要实现的功能就不是 Authorization header 设计出来要解决的问题。

当然楼主的需求也有解决方案,在🪛上焊一个🔨的头就可以了:token 变成动态的,一个 token 只能被使用一次,而生成 token 的逻辑需要进行各种加密混淆以提高破解的成本。缺点也很明显,🪛柄太细,容易断(任何在客户端实现的逻辑都是可以被破解的)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/856998

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX