从 npm 投毒事件思考,我写了一个基于 FUSE 的 macOS 文件守护工具 Shield

5 月 12 日
 vone

最近一段时间发生了多次投毒事件,恶意代码随意读取 ~/.ssh 、.npmrc 、等机密文件然后静默上传。整个过程中系统没有任何阻拦。机密文件的泄露后导致的密钥轮换工作操作了不少额外的工作和风险,所以最近 Vibe Coding 了一个简单的工具,来尝试解决这个问题。

下面简单介绍一下开发的思路和实现原理,更详细内容可以阅读 https://www.npmjs.com/package/@yangch/shieldREADME.md

它做了什么

Shield 是一个基于 FUSE (用户空间文件系统) 的 macOS 命令行工具,能让你指定的敏感文件在被任何进程读取时,弹出一个原生对话框问你“允许还是拒绝”。

技术实现细节

核心流程只有三步:文件重定向 → FUSE 拦截 → 用户授权。

1.存储与重定向

当你执行 shield add ~/.ssh/id_rsa 时:

原始文件被移动到 /usr/local/var/shield/storage/ 下对应的路径

原位置创建一个符号链接,指向 FUSE 挂载点 /usr/local/var/shield/mount/ 下的相同路径

之后,任何对 ~/.ssh/id_rsa 的读写都会经过这个 FUSE 挂载点,由守护进程接管。

2.FUSE 层拦截

Shield 内部运行一个 shield-daemon ,它通过 FUSE 实现了一个简单的文件系统。当进程执行 open() 调用试图打开受保护的文件时,内核将该调用转发到守护进程的 FUSE 处理函数。

这里使用的是 fuse-t (推荐,无需内核扩展,支持 macOS 13+),也可以回退到 macFUSE 。整个拦截发生在用户空间,不影响系统稳定性。

3.用户授权对话框

守护进程收到访问请求后,通过调起一个原生 macOS 对话框,选择 Allow 会放行本次读取,并缓存授权 10 秒。在这 10 秒内,同一文件再次被读不会重复弹窗,避免频繁打扰。选择 Deny 则直接返回错误给调用方,调用方会收到类似 Operation not permitted 的结果,文件内容不会被泄露。

所有授权/拒绝决定都会被写入日志,事后可以审计。

4.后台驻留

Shield 作为 launchd 服务运行,开机自启。用户可以通过 shield start/stop/status 管理守护进程,不占用 Dock 或菜单栏,静默运行。

安装与使用

# 先安装 fuse-t (推荐,无 kext )
brew install fuse-t

# 安装 Shield
sudo npm install -g @yangch/shield

# 初始化并启动服务
sudo shield install

# 添加要保护的文件
sudo shield add ~/.ssh/id_rsa
sudo shield add ~/.aws/credentials
sudo shield add ~/.npmrc

# 查看守护列表
shield list
# 移除保护(会还原文件到原始位置)
sudo shield remove ~/.ssh/id_rsa

之后只要你在使用系统,任何对受保护文件的读取都会弹窗询问。

一些说明

1 、只支持 macOS ,推荐使用 fuse-t (用户空间,无需批准内核扩展),Windows 暂时还没有支持。

2 、目前只拦截了文件的访问,但是并未对原文件做加密,只能阻拦有针对性的机密文件获取。

1574 次点击
所在节点    程序员
3 条回复
yangg
5 月 12 日
这个是个不错的方向
xylophone21
5 月 12 日
比如 ~/.aws/credentials 文件,
- 如果使用 aws cli 进程或者 skill 的脚本来读取, 则是合法的,配置后自动授权
- 如果其他进程来读取,比如 AI 直接读, 临时专项的脚本等, 则弹出授权

原理上可以实现吗
vone
5 月 12 日
@xylophone21 取决于 FUSE 的实现方式。
1 、在 Linux 、Windows 上读取访问进程名是没问题的。
2 、在 MacOS 上如果是 macFUSE 可以读取访问进程名,但是 macFUSE 的安装需要通过内核扩展,目前安装比较麻烦。目前我推荐使用的 fuse-t 是基于 NFS 协议实现的,无法获取访问进程名。
3 、在 MacOS 上也可以通过 ESF 框架实现,但是这个权限 Apple 官方审核很严格,只针对大型安全公司开放。
4 、在 MacOS 上推荐使用 fuse-t
所以结论就是:MacOS 不太行,其他系统可以。

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

https://v2ex.ih06.com/t/1212135

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

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

© 2021 V2EX