怎么做一个匿名论坛

Posted on Mar 21, 2022

支持使用匿名的方式表达对公司各项政策的意见,是我司的一项光荣传统,然而在具体操作过程中,也出了一些问题和波折。

最初很长一段时间我们使用的是Slido服务,这个网站的本意是用来在公开演讲的时候观众向主持人提问的,我们发现用它来做一个匿名论坛也是不错的。

随着公司发展,人数逐渐变多,slido的一些问题也暴露出来了。最为明显的是它是没有注册的,用户只需要自己填写一个id就可以穿上马甲进论坛了,因为id信息只记录在cookie中,我们可以简单地通过浏览隐身窗口给自己套上多个马甲,这样随便一个有心人就能搞出声势浩大的样子。显然,它保证不了“一人一票”这个最基本的民主诉求。另外还有一个巨大的风险:万一出现诽谤诬陷等涉及违法犯罪的消息,我们是没有任何兜底方法去把对应的人找出来的。

后来我们的办公套件用上了先进的飞书,然后匿名论坛也换成使用飞书自带的“公司圈”,它使用了比较经典的“前台匿名,后台实名”模式,即每个人的身份和马甲有一一对应的关系,只不过这个对应关系没有人有权查看,除非出现涉及违法等少数特殊情况。

不得不说,这种模式很好地解决了slido的两个主要缺点。但它也并非完美,抛开“我们是否能信任大厂和大厂员工的职业操守”这种根基性问题不谈,实践中因为实名与匿名的对应关系实际遍布在服务器进程的整个内存空间,需要通过精细的业务逻辑控制不让这层对应关系在前台泄漏,其实很容易一个bug就直接交待了。

这里以我自己发现的一个bug为例来试说明严格保持身份信息不暴露的难度:当用户给匿名论坛中发布的实名评论点赞,并且将评论点赞成热门评论,此时热门评论里会以实名信息显示点赞列表,同时实名评论的作者收到的点赞通知内的用户名是匿名的,于是整个点赞列表的身份信息就全暴露了。

上面的例子还隐含了一个相对隐晦的问题:不同用户所能看到的界面和掌握的信息不一样,身份已经暴露的用户可能完全不自知。这里可以展开再举个例子,所有人都知道即使是论坛管理员也看不到用户身份信息,但是大家不知道的是管理员是可以在后台看到所有的发贴和删贴记录的。实际上我隔三岔五就能在后台看到有人先是用实名发了一贴,然后意识到自己忘了切匿名,于是删帖并用匿名再重新发一次……只要我不主动说,他们不会意识到他们已经是纯裸奔状态了。

故事讲差不多了,我们来从头梳理一下做一个靠谱实用的匿名论坛到底应该怎么做。

1. 真匿名

相对于“前台匿名,后台实名”,真匿名即实名信息不存放在服务器或数据库中。假匿名的问题其实不只是出bug会泄密,还有比如被黑客手段拿到数据,或者DBA监守自盗,风险无处不在,最安全的就是直接没有实名信息,也就无从泄漏了。

2. 一人一账号

这个是民主的基本诉求。思考一下会发现“一人一账号”和“真匿名”是有些矛盾的,意味着至少在注册阶段,账号需要跟实名有一些联系(不能做成slido那样)。

一种比较简单直接的做法是“抓阄”:根据总人数提前创建好X个账号,打印成纸条塞到一个大布袋里,每人摸一个就完事了。

现实情况会更复杂一些,比如公司的员工列表不是一成不变的——不断有人加入有人离开。不管是入职当天发放账号,还是入职累积够一定人数后组织发放,账号的激活时间都泄漏了真实身份相关的部分信息。

可能的改进方法是每隔一段时间(比如半年),作废所有账号,来一次全员重新发放。这么做的缺点是用户在匿名状态下维护的“人设”没了延续性,体验不太好。

另一种办法是放弃严格的一人一账号,每半年所有人都可以重新申请领取账号。这么做老员工手上会有多个号,有效利用会有更大的话语权,这个看怎么理解了,可以认为是一种福利。这么做的另一个好处是,万一不小心人设崩塌了,总是有重新来过的机会。

此外要考虑“抓阄”的可操作性问题,尤其是我们公司是分布式办公的,不可能把所有人聚到一起,如果分办公室来也面临泄漏部分身份信息的问题。因此我利用所学不多的密码学,想了一种可以在网络上完成了方法,我愿称之为“赛博抓阄”。

赛博抓阄

  1. 参与抓阄的每个人自己用 rsa 生成密钥对,把公钥提交进系统。
  2. 组织方以直播的方式运行一个脚本:这个脚本在内存中生成X个rsa密钥对,公钥直接保存进匿名论坛账号数据库,私钥在内存中随机打乱顺序,然后分别使用步骤1中提供的1个公钥加密后保存进文件。因为打乱后私钥的顺序只在存在于内存中,脚本退出后就无迹可寻了。
  3. 每个人用自己的私钥解开步骤2中使用自己的公钥加密后的密钥,可以得到一个账户私钥,用于之后的匿名论坛登录。

为了提高第2步中的可信度,我们可以当场 review 代码(应该不会长),还可以现场去 aws 等平台申请一台服务器来排除环境污染的风险。

3. 特殊情况可以追查实名信息

这个是为了应对法律风险。这条规则看起来似乎跟“真匿名”的矛盾更显然,不过我们只要保证把实名信息(也就是“抓阄”记录)存放在匿名论坛系统之外就没问题了,而且为了安全,我们可以选出若干个民意代表,规定查看实名信息需要至少X人同意。

这个在密码学上也是可以做到的,使用秘密分享加密方法,把实名信息拆成N份,并且还可以设置到时候解开信息需要至少X人提供密钥。

4. 操作记录透明公开可追溯

匿名论坛可以允许有不同角色和权限,但是不同人所能观察到的信息应该是一致的,否则其根基性的身份安全将受到威胁,极端情况就是前面说过的裸奔而不自知。

另外,匿名论坛的帖子不能删除,不能修改(如果允许修改则应保存修改记录)。这个规则同样是为了保证不同人观察到的信息是一致的,不应该因为某个人在特定的时间打开了论坛就掌握了更多信息。

5. 紧急逃生通道

如果用户发现自己不小心身份暴露或者人设崩塌,可以使用一键逃生功能,停用账号并销毁自己的所有记录。这条乍看来跟上一条是有矛盾的,但是从更底层的逻辑上来说,第4条是为了避免用户身份暴露而不自知,这一条是为了用户身份暴露的情况下减少损失,两者都是为了用户能更有安全感地畅所欲言。

6. 信道安全

为了打消用户对公司内网(或远程VPN)网络监听的顾虑,匿名论坛应该部署在公开网络。这样可能会涉及到离职员工账号的问题,可以考虑给论坛多设置一个定期更新的全局密码,或者干脆定期更新地址。

总结

感觉其实不怎么难,有时间可以考虑做个原型,先挖个坑。