请 [吸词] 的作者出来解释一下密码明文传输的问题

2024-05-23 16:27:24 +08:00
 rambo92
今天忽然发现所有的网站的请求里都有一个固定的 url 请求:POST https://jnexswpfgysrqlagwajs.supabase.co/auth/v1/token?grant_type=password
Request Body 携带了一个我常用的用户名和密码,而密码居然是明文的!!!
这让我很是震惊,密码泄露了???

于是开始排查:
1. 打开无痕模式:随便打开个网站,没发现这个请求,于是确定跟插件有关;
2. 关闭所有插件,一个一个打开,最后定位到 [吸词]

原因找到了,那么这个是为什么呢?
1. 为什么密码要明文传输?
2. 为什么所有网站的请求都会发这个请求?插件干啥了?

https://cnnbrba5g6haaugeu530.baseapi.memfiredb.com/storage/v1/object/public/images/public/1.png
14754 次点击
所在节点    程序员
109 条回复
dode
2024-05-23 17:32:33 +08:00
我认为 HTTPS 服务,明文密码是正常的行为
ntedshen
2024-05-23 17:33:29 +08:00
前端做加盐哈希能防脱裤。。。这理论不亚于戴个贞操锁然后把钥匙别在边上。。。
后端好歹还塞在里面,要先亲密接触一下隔夜饭才能拿出来。。。

不过
https://jnexswpfgysrqlagwajs.supabase.co
这个域名确实写在 1.0.9 版的 crx 安装包的的 chunk-7bd2bbc8.js 里

grant_type=password 请求从属于 signInWithPassword 方法

向上
yr = async (n, e) => {
const {data: t, error: s} = await se.auth.signInWithPassword({email: n, password: e});
t.user && await ze.storage.sync.set({[ye]: {email: n, password: e}}), s && console.error(s);
}
jt = async () => {
const n = await ze.storage.sync.get(ye);
if (!n[ye]) return;
const {email: e, password: t} = n[ye], s = await Ce();
return (!s || s.email !== e) && await yr(e, t), e;
}

继续向上则是
kr = async (n, e = 0) => {
if (!await jt()) return !1;
const s = await Ce();
if (!s || !await Rt()) return !1;
const i = await br(n.name, n.origin, s.id);
if (i && i.length > 0) return !0;
const {error: a} = await se.from("words").insert([{...n, user_id: s.id}]);
return a ? e >= 2 ? !1 : kr(n, e + 1) : !0;
}, Sr = async (n, e = 0) => {
if (!await jt()) return;
const s = await Ce();
if (!s || !await Rt()) return;
const {error: i} = await se.from("words").delete().match({name: n, user_id: s.id});
if (i) {
if (e >= 2) return;
Sr(n, e + 1);
}
}
这个看起来已经是功能模块了
可见问题应当出现在 jt 方法,当 kr 和 Sr 试图保存单词的时候发现没有登录成功或者没有建立对应的数据库,因此自动尝试登录

至于为啥这么蠢别问我。。。反正不是我写的。。。
abelyao
2024-05-23 17:42:00 +08:00
恕我直言,在前端给密码套 md5 然后传给后端,简直是傻 X 行为,不是你入行多久就是对的
rambo92
2024-05-23 17:45:53 +08:00
@Trim21 没细看,太长了,只看了第一页的一半大概

@dode 嗯,个人观点

@ntedshen 感谢代码分析
另外贞操锁钥匙别外面这个比喻不太恰当,如果仅仅 hash 的话这么说没毛病,毕竟大部分用的 hash 函数都是 md5 ;
而加盐哈希,每个服务的盐不同,相同的密码得到的摘要也不同,更像是每个服务都有自己的贞操锁
tsanie
2024-05-23 17:46:35 +08:00
摘要入库是没有任何异议的,但密码通过有保障的通道( https )明文到达后端是合理需求,否则后端如何做密码强度验证?

强度验证放到前端做才是真的会有安全问题。
LieNoWell
2024-05-23 17:49:03 +08:00
@rambo92 #40
你一直说加盐加盐,盐值存在哪里呢?
mogita
2024-05-23 17:50:21 +08:00
在 HTTPS 上传明文密码无可指摘
FTLIKON
2024-05-23 17:50:24 +08:00
@rambo92 #44 前端加盐 hash ,你加的盐遇到个会扒你前端源码的不是分分钟就被破解了吗?
Goooooos
2024-05-23 17:51:32 +08:00
客户端 hash 后传给服务端,其实被人拿到 hash 后的密码也可以直接登录
跟传明文没差别,好处就是如果这个人多个网站用同一个用户名和密码可以减少其他网站被牵连,还有这么点用
rambo92
2024-05-23 17:51:34 +08:00
@abelyao 无论你的还是我的,都是个人观点,可以给出论据来讨论,直接傻叉的话这话并没有分量。

我入行才 9 年多,也不算久,说 14 年入行也不是为了说明自己资历老就是对的,而是说明一下刚入行的时候就接受了这个观点的影响
javalaw2010
2024-05-23 17:52:15 +08:00
我本身是不想参与 V2 这种月经贴的讨论的,不过今天实在是太闲了,秉持着真理越辩越明的理论,我还是想再多理论两句。
> 密码加盐(每个网站的盐一般都不同)后 hash 传输,服务端存储的是与原明文密码没有任何逆向关系的字符串,所以即使多个网站使用相同的密码,也不会受到某个网站被脱裤后的影响

其实稍有编程常识的后端开发都会选择加密入库,不可能有人选择加密入库的。不过我们假设就有这样一个刚入行的愣头青,写了个明文入库的代码,好巧不巧,他被拖库了。黑客拿到了份数据库,得到了一个( xiaoming, password123 )的账户名和密码,他想使这样一个用户名密码来登录一个前端加密网站,此时他选择了最简单的办法,手动输入,他在用户名输入框里输入了 xiaoming ,在密码框里输入了 password123 ,而当时小明也在该网站输入了同样的用户名和密码,此时黑客点击登录,那么你觉得他是能登进去呢,还是不能呢?

> 基于第一点,HTTPS 是否是加密传输其实无所谓的,与密码的安全并无关系,遑论还有中间人攻击呢(不知道说的对不对,印象中是这个)
我不太明白是什么可以得出了 HTTPS 和密码的安全无关这样一个结论的,而中间人攻击,你的网站/APP/操作系统必须信任一个原则上不可信的第三方证书,中间人攻击才能得以实施。这意味着要么你主动信任了一个不可信的中间人,要么黑客得到了你的操作系统的控制权。而中间人攻击一旦得以成功实施,经过前端加密的密码,也不过是变成了另一个密码的明文而已。

实际上,要真正解决密码被拖库的碰撞问题,要使用的解决方案是二因素认证,而不是前端加密。
kads
2024-05-23 17:53:39 +08:00
首先,装不安全的插件本来身就是不安全的。明文有可能泄露的风险,但是极小概率的。在你网站输入的时候,更容易获取的你的密码而不需要中间人攻击,这个攻击也很难实现,需要证书。在前端无法保证传输的安全,只能在后端加密保存。即使他们不知道的密码 也可以重放攻击
BeautifulSoap
2024-05-23 17:54:02 +08:00
真的是叹为观止,这就是不光没有开发经验,连基本 it 知识和安全思维的没有的人的反应。提出的前端加盐 hash 更是逆天
dcsuibian
2024-05-23 17:56:45 +08:00
前端哈希主要是防止后端不小心在日志中把密码打出来
43n5Z6GyW39943pj
2024-05-23 18:01:49 +08:00
前端加密✌️=放屁
abelyao
2024-05-23 18:02:49 +08:00
@rambo92 我并没有想提供很多论据跟你讨论谁对谁错谁更有说服力,无论是理由还是相关讨论在 V2 在互联网都有很多,你愿不愿意接受这个事实都是你的事,我只是纯粹说这个行为是傻叉行为,你愿意继续 hash 就继续 hash ,没有要说服你或非要你能理解的想法
cnevil
2024-05-23 18:18:22 +08:00
https 就相当于是加密了。。你再加一次有什么用呢
前端对字符串加密跟明文没任何区别,如果我能从你 https 里获取到了原始的请求体内容,依旧可以用这个加密后的字符串进行重放,这个加密后的密文就等于你的明文密码,不知道你能不能想明白这个道理
除非你每次登录都重新生成一对密钥
rambo92
2024-05-23 18:42:02 +08:00
我的“前端需要 hash 传输密码”的观点,是建立在传输通道不安全(非源头,如 web 、iOS 等)的前提下,因为当时使用 http 的服务还有不少,加盐 hash 是为了防止传输通道被入侵时拿到明文密码;而在 https 是安全且极难入侵的传输通道的前提下,那我的观点的前提就不成立了。感谢普及 https 安全性的 v 友。

此外我有个问题希望和大家讨论一下:
密码是否应该在整个服务的流转过程中都是安全且不可接触的呢?
换句话说,如果服务端接收且打印了(或其他形式)明文密码,而这个信息可以被普通权限的开发者或员工接触到的话,作为用户是否可以接受呢?
jianchang512
2024-05-23 18:51:30 +08:00
一般前端想 hash 密码,多是防止这 2 个问题吧

1. https 传输过程中泄露,加密后即使泄露也不会被看到真实密码
2. 后端可能会将请求信息打入日志,如果未加密可能会出现直接密码明文显示在日志里



前端 hash 防的从来不是脱裤,没有哪个后端会直接明文存入密码吧,至少得一层 md5 吧,如果被脱裤明文泄露,问题也是后端,和前端毫不相干。
rambo92
2024-05-23 18:58:43 +08:00
@javalaw2010 感谢讨论。
这两点都是建立在传输通道不安全的基础上得出的结论,就是不光 http 不安全,也不放心 https 的安全性,认为都有可能被入侵而拿到传输的密码明文。
既然大家都认同 https 是安全且极难入侵的,那么我的观点的前提就不成立了。

第一个问题:能登陆,都拿到明文密码了,反过来就不行了(这也是 hash 存储的目的);而前端 hash 的目的是防止在传输通道拿到明文,我前面说的脱裤的例子是错误的,无法证明这个手段和目的的合理性。

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

https://ex.noerr.eu.org/t/1043320

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

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

© 2021 V2EX