对微博被恶意加关注问题的一点分析和猜测
起因
我是微博重度用户。
在国庆节前后几天,我遭遇了一轮又一轮的被动加关注问题,刚开始以为自己不小心泄露了密码,因为之前很长时间我都没有遇到过这类问题,先从自己身上找原因。然后就是既定流程:修改密码 -> 在安全中心退出所有已登录设备 -> 清空所有第三方授权。
然后,好像并没有什么用。
很多人认为是微博内部故意设计了一套策略,强行给用户塞关注来赚黑心钱,但我认为这个说法站不住脚,微博这两年市值和营收一直涨,不需要冒风险捞这种钱。
于此同时,我看了我身边的一些人身上也发生了同样的问题,以及 V2EX 里也有多个人发帖:
新浪微博被 wt.weidaogou.com.cn 等垃圾推广号包围了
大家惊讶地发现彼此遇到的可能是同一波人,被强加的关注有很高的重叠率,套路也都类似,要么是发表各种 copy 来的文章、视频不知名营销号,要么就直接脸都不要直接给你发硬广。
思考
镇定下来,再次思考一下,到底哪个地方出了问题?哪个地方能出问题?
从技术实现上看,能给我的微博帐号加关注的,通常只有三个途径:1. 我的帐号被盗,能直接被别人登录上去。2. 我使用的第三方客户端等可以通过微博开放平台走 OAuth 拿到 access token,然后权限被滥用。3. 我在浏览器上使用 Web 版微博时,cookies 被泄露。这个可能性最大,因为很早就听说过做微博黑产的,和运营商合作后劫持微博的流量,给用户塞关注,挣钱不要太容易。
我首先排除掉了盗号这一途径,一方面我修改后的密码是 1Password 生成的随机密码,没可能被碰撞或猜出来,另一方面我登录时刻意看过是 HTTPS,可以认为这个流程中不会泄露密码给其他人。我的电脑使用习惯良好,中木马的可能性也几乎没有。
然后考虑第三方授权的问题,我在第一次修改密码清空所有授权后,再次把授权给出去的只有我 Mac 上的客户端 Maipo 和手机上的几个微博客户端:WeicoPro,Cosmos,微博国际版,微博官方版。
微博官方版和国际版可以信任,排除掉,然后看 Weico 和 Cosmos,接上 Charles,抓所有的请求下来看,没有发现它们会往其他地方上传敏感信息,微博的 api 接口也是 HTTPS。
解不开 Maipo 的 HTTPS 请求,尴尬。难道这个客户端里 Pin 了公钥?有点不科学。先不管了,反正走的是 HTTPS 就行。只是有一个 http 请求不太正常,但这是授权成功后发往开发者服务器的请求,里面即使带了 access_token 其实也没关系,因为其他人没有开发者手上的 secret key 啥也干不了。(更新:经 Maipo 开发者提醒,有 access_token 就可以做关注操作,不需要应用私钥签名,所以这一步的分析是不够准确的,但目前没有发现黑产会劫持第三方应用的回调请求的迹象。access_token 通过 HTTP 传递是不安全的行为)
我目前在使用的这几个客户端要么官方,要么老牌,要么开发者是我信任的,几乎可以排除它们的嫌疑。
控制变量,缩小范围
那么,只剩第三种可能了。我用的 Web 版微博在某个地方泄露了 cookies,导致我的帐号被临时性盗用。但是我作为一个好歹有一些信息安全基础的人,在今年 8 月份微博主站上了 HTTPS 后,就一直用的 HTTPS,哪里还能被偷到 cookie 呢?
想不明白,那先放一放,做点其他的尝试:再次走一遍修改密码取消授权的流程,然后只在 Web 版和官方 App 上使用微博,其他地方一律不再登录。
这样尝试了 3 天后,我没有再遇到加关注的问题。
和我预期的不一致,这好像是在刁难我胖虎了。
看起来这事和微博 Web 版没有关系?我错怪 Web 版了?
那就把非官方客户端一个个恢复使用,首先是 Mac 上的 Maipo
使用 Maipo 一天后,加关注的问题又来了。看起来 Maipo 会引入这个问题。
可是 Maipo 的开发者是微博员工,他是最不可能在背地里利用微博干坏事的,而且从其他人的反馈看,他们没有使用 Maipo 也遭遇了这个问题。我无法把原因归结到 Maipo 身上。
又思考了一天,以前 debug 代码的经验突然给了我另一个想法:Maipo 的某些行为会触发 Web 版微博泄露 cookie,这不是单方面的谁的问题,而是两者同时存在时才会产生的问题。
找了一圈,Maipo 里能和 Web 版产生关系的,我只能找到一个操作:View on Weibo.com
这个是在 Maipo 里对某一条微博进行的动作,执行后会在浏览器里打开这条微博的链接。开启浏览器的抓包,尝试做一次 View on Weibo.com
我发现了什么! Maipo 打开微博的链接是 HTTP 的,虽然访问后会 301 跳转到 HTTPS,但这个 HTTP 请求仍然会携带上浏览器在 weibo.com 域下的所有 cookie
在 Charlse 里看到请求头的那一瞬间,好像所有的谜团都解开了一样。
结论
那么,这一切都可以有一个合理的解释了:
微博黑产在运营商线路上劫持 http://weibo.com 的 HTTP 请求,窃取用户 cookie,然后通过 cookie 给用户加关注。
虽然微博主站已经上了 HTTPS,但用户登录后的 cookie 没有设置 secure,导致用户访问 HTTP 链接时虽然会被 301 到 HTTPS 上,但也会携带有效 cookie 出去,被运营商劫持。
清除授权、修改密码都没有用,只要你登录后在某个特定场景访问到了 HTTP 的微博链接,那就很可能中招。只是在微博 Web 版站内的话没问题,因为默认都是 HTTPS 了,但是你的浏览器书签、别人发给你的链接、旧的外链、其他应用生成的链接都可能还是 HTTP 的。
需要注意的是,以上的结论来自于对比实验和技术可行性分析后的猜测,没有任何的实锤证据可以证明结论的正确性。微博官方应该可以根据访问记录查出来,我没法查,只能合理假设。
防御措施
不指望微博会给 cookie 设置 secure 了或者上 HSTS ( HTTP Strict Transport Security ) 了,他们有业务上的考虑。但是作为用户,肯定还是有办法解决问题的。比较彻底的做法是在家里路由器层级上自己劫持微博的 HTTP 请求,直接 301 到 HTTPS,比较 geek。
更简单的做法是,自己往 Chrome 浏览器的 HSTS 列表里加入 weibo.com 域名:
在 Chrome 里打开 chrome://net-internals/#hsts
Add weibo.com
Query weibo.com ,能查询到就可以了。如下图:
把 weibo.com 加到 HSTS 里后,Chrome 再遇到 HTTP 的微博链接,会直接在浏览器内部就跳转到 HTTPS,请求不传到外面去,可以保证通讯安全。然后,你就不要在其他的浏览器或电脑上登录微博了。
我平时用的都是 Chrome,Safari 我没找到哪里可以自己添加 HSTS,Firefox 好像可以修改配置文件夹里的 SiteSecurityServiceState.txt 来实现,我没试。
被这个问题困扰的同学可以试试看,我这边是有效的,不知道其他人情况如何,欢迎反馈结果。
原文发表于知乎专栏:https://zhuanlan.zhihu.com/p/30007232