曾经有人说过,头脑是最好的杀毒软件,但在来到我们最爱的大中招时代后,这句话严格来说得变一变了,毕竟人脑的处理能力是有极限的。
供应链和无尽的依赖
虽然说这段标题和日本人的轻小说似的,但内容可远没有那么愉快了。现代软件的复杂和冗余性已经达到了一个前所未有的高度。为了省一点点开发时间,所有人肆无忌惮的拉入在网上找到的现成产品,毕竟拉依赖能干出什么坏事呢?而且过去的那种依靠商业公司做好的中间件开发的流程也已经在银行业和外包以外的地方退环境了。
自带一个足够大的标准库的语言相对来说还好,大家不需要因为一些极为基础的功能拉入或被自己所需要的功能间接拉入一些奇怪的外部库。但有些不自带或设计模式非常奇怪的语言就没有这种幸运天赋了,很多时候开发者甚至不知道自己的程序通过什么方式拉入了什么人写的什么代码。
由于现代软件(不幸的)进步,甚至已经编译好下载到本机的代码也未必是安全的:不少现代软件依赖品种繁多的在线下载服务、热更新服务、乃至每次启动时都要从服务端拉取动态执行内容的功能,导致每一次打开软件就像一场大冒险。
投毒服务大减价
在过去,供应链投毒其实没那么常见,因为它需要极高的成本和耐心,往往只会被某些想要从某些人身上爆出巨量金币或资料的大人物利用。但时代变了,如今投毒的成本已经大大降低,也算是一种科技带来的生产力提高吧。
在现在,一个小小的钓鱼邮件或者看起来没恶意的插件就可以接管某个平台上(你们知道我说的是谁,毕竟每次出事都有他)知名开发者的凭据,拿着这个凭据又可以在这些被依赖的包中种下木马,从而拿到更多开发者的凭据,甚至还可以在使用了这些软件或代码的浏览器插件、编辑器插件、桌面程序等更多地方指数级的扩大影响力,甚至还能在原始问题被修复后开出快慢刀:窃取的凭据很多情况下并不会被吊销,在它们的所有者放松警惕后可以被延后利用。甚至有些情况下,中招的厂商可能会出于某些原因故意无视或拖延问题的暴露。
中间人,新型中间人和更大更好的中间人
虽然随着免费 SSL 证书的普及以及 TLS 协议的进化,只要不使用某些神奇的浏览器,对于一般用户来说传统派芙蓉王中间人可以说基本上已经结束了,但锐刻牌新型中间人已经崛起,一代人有一代人的使命可以说是。
网站或程序对基础设施的信任也能被滥用,利用者完全可以注册过期的软件自动更新域名、收购或“善意接管”开源程序或公共加速服务,成为隐形的中间人,从而在接入了这些服务的地方打出意想不到的伤害。毕竟大多数情况下开发者并不会想到这些公共的,看起来很好用的服务很可能在之后的某一天给你报一个大的。
更进一步讲,现在我们有了大家喜欢的电子牛马,很多人无法或不舍得购买原厂的这种牛马,因此选择了一些二手或经销商购买这些服务,经销商作为天然的中间人,在你给了电子牛马足够权限的情况下,可以轻易的让词元反过来流,接着电子牛马成为他们的主人(此处应该有司墨丨哥的大头,但太吓人了我不想放在这里),拿到牛马有的一切权限。而有些情况下甚至更糟糕,电子牛马的原厂完全有可能也做出同样的事:大家都知道哪些信奉什么有效利他,有效加速主义的什么黑暗启蒙疯子总觉得自己是上帝,万一哪一天某位大仙发出了你崛起罢的鬼动静,恐怕使用电子牛马的诸君要喜提一份全家桶了。(我向你保证这里绝对没有讽刺某位百度前员工的意思)
贡献者最好是在做贡献
甚至 Pull Request 也有可能成为下毒的一手:尽管大部分人确实是为了添砖加瓦,最坏的也可能只是为了刷点 PR 塞进自己的简历里,但还有一些闲的蛋疼的人可能就是为了找点事做或者破坏整个世界来投毒,比如说某个明尼苏达大学的神人,还有 Libbitcoin Explorer 的作者。而且现在的大型软件工程很难说有足够的成本去验证每一个问题或者修复的真实性,毕竟吃着免费的供应链软件的人显然是不想付账的。
当奈公何?
怎么办呢?说句老实话,我也不知道。尽管现在市面上有许多的供应链安全服务,能够在发现问题后及时报警处理,但在被发现之前的时间差中造成的损失却没有办法挽回了。
传统的安全软件依赖指纹的拦截方式很难说能对最新最热的恶意代码造成什么损害,而主机入侵检测系统和强制访问控制系统很难以正常用户能接受的粒度去预防这些攻击:一个用于发布更新的程序访问网络和访问本地的验证凭据很难说行为有什么问题,但你在不劫持流量的情况下怎么把这个行为和偷了你的凭据传到 C2 的操作区分开来呢?对于一般用户和非企业开发者来说,做全量流量解密和分析既不安全也不经济。人工审核更是不可能的事,某个设计不良现代语言的几个常用框架轻轻松松就能拉入以兆计算的代码,目前地球上应该还没有能在合理的时间内逐个仔细检查其中内容的技术。
也许桌面用户能自救的最好办法就是使用传统派软件:尽可能避免使用带有热更新等功能的程序。但总有一些是你避不开的,这时候就需要应用程序沙盘等功能去做纵深防御。
至于开发者,除了避免一些过于动态或缺少基础功能的语言就没有什么合适的解决办法了。有人尝试过让依赖管理系统只拉取经过一定时间,积累了一定声誉的依赖,但只要你的依赖上游中有一个没做好这件事的,这种防御也就形同虚设了,况且这个产品关联的几大惯犯目前并没有任何解决这个问题的想法。
在前端方面,SRI 能解决通过外部资源引入的投毒风险,但你构建时本身引入的不可信代码就没什么解决方案了,而且前端也不存在什么可重现编译功能,不少人也不会在本地使用不会自动更新的 npm ci 安装依赖,而是直接 npm 或者 yarn 一把梭。(自动更新可能有好处,但是更有可能成为万恶之源,特别是你用的软件作者不会反转二叉树的时候)。
末法之世的参考文献
也许你会觉得上面说的这些事都是笑话,但不幸的是,每一段话都有佛陀也要闭上眼睛的留着血与泪的故事,下面将会给出魔法芝士这个侧面的引文:
- 执行动态内容,故意隐瞒问题发生:ApiFox 投毒事件
- 钓鱼邮件窃取 Token:Josh Junon NPM 凭据被鱼叉攻击事件等
- 延迟爆炸的凭据窃取:Mini Sha-Hulud 投毒事件导致 OpenSearch,TanStack
- CDN 投毒事件:来自荷兰一群伙伴,结庐东南亚(荷兰老乡投毒)
- 开源软件收购:还是上面的荷兰老乡,你就说中不中吧(上边那位收购 GoEdge 等)
- 这条算送的,上面捞翔还使用三角测量的 1Day 重拳出击过。

发表回复