零宽空格引发的问题

有人跟我反馈说有bug。

我说:啥bug?

对方说:刚申请的内部用户的账号登录不上去。

我说:还有这种事,报啥错?

登录的时候报了这个错:

图片

我一看还好还好,跟上一次不一样的错,不然我都觉得我穿越回去了。

我脑子都不动一下,直接回复:是不是输入空格了?我看之前的逻辑是不会自动去除首尾空格的。

对方答:

图片

我不信邪,要到账号密码(密码是建立账号后通过邮箱发送的),自己实验了一下,还真的登不上去。

奇了怪了,这块逻辑我看了下,实现很简单,大概逻辑简化后的代码如下:

User user = userService.getOne(username,password);
if (Objects.isnull(user)) {
 throw new Exception("用户或密码错误");
}

这里的 username 是员工姓名,这个实现我觉得很奇葩...重名了咋办?

搜索条件加了密码避免了重名的情况....

但万一密码一样且重名呢??

理论上这个概率比较低,因为密码够复杂,长度必须为 18 位,且必须包含字母大小写、数字和特殊符号,但是确实是有这个可能,所以为啥不能用手机号当登录账号呢?

算了,不纠结这个,还是来看看为啥登录不上去吧!

看着报错,肯定就是 user 没找到呗,那么我自己输入了一遍账号和密码,确认没输错,于是就怀疑起密码,难道是邮寄发送的密码和数据库实际存储的不一样?

我登上数据库,利用 username 查询这条记录,想对比下密码,发现竟然找不到这条记录??

(假设这个 username 是 aaa)

select * from user where username='aaa';

图片

我的发?难道是账号没生成?

因为发邮件和数据库保存账号肯定不是一个事务操作,所以有几率会发生这种情况。

随即我按照 id 倒序取最新五条看看最近的记录都是啥,又发现有 aaa 这条记录???

我的发?见鬼了吗?

突然开始怀疑这个 username 的格式,直接在阿里云 dms 上点开这个字段,果然发现了猫腻!

图片

可以看到名字中间有红点,而正常的名字中间都是没红点的,那么这个红点是什么玩意?

我把红点拷贝出来,直接一个urlEncode,从界面可以看到输入那边完全看不出有任何东西,但是实际 encode 是有值的:

图片

%E2%80%8B 这又是啥玩意?我直接一个搜索:

图片

零宽空格!!好吧,懂了,破案了,怪不得数据没匹配上!

图片

简单理解就是这个字符正常情况下肉眼不可见,但是它确实存在,所以手输的 aaa 匹配不上存在数据库里面的 aaa,因为数据库的aaa夹了看不见的"内鬼"啊!。

除了零宽空格,还有别的零宽字符,比如零宽非断空格符、零宽度连字符等等,特性都是非打印,即肉眼不可见。

它们可以用来实现隐形水印或者信息加密。

我找了个网站,咱们看看效果:

图片

比如我将'你好'和'好个屁'混合了一下,得到右边的'你好'。

此时复制右边的'你好',decode 以下就能得到隐写的'好个屁':

图片

原理也很简单,将要加密的字符转成二进制,然后按照一定的规则翻译,比如1转成零度空格符、0转成零宽非断空格符,字母间隔用零宽连接符分隔。

然后解密的时候按照上述规则翻译过来即可。

网址贴这里的,有兴趣的可以自己去玩玩 :https://yuanfux.github.io/zero-width-web/

最后我直接把这个姓名重新编辑了一下就好了,操作人员因为是从工单上复制姓名,所以才搞出了这个零宽字符,后续让他手输!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值