让 AI Agent 帮我修了个安全漏洞——Hermes 接 Gmail 查 Supabase 实战
那天打开电脑,Gmail 里躺着一条来自 Supabase 的未读邮件,标题直白得让人没法忽视:
Action required: security vulnerabilities detected in your projects
点开一看,是我的 umami-v2 项目 —— 一个跑了快两年的网站分析工具,Supabase 当数据库。邮件说检测到了安全漏洞,数据可能被未授权访问。
当时我正在试用 Hermes Agent,心想:要不就让 AI 去处理这件事?从看邮件、到排查问题、再到修漏洞,全程让它来。
这篇文章记录的就是整个过程:接 Gmail、读邮件、登 Supabase、写 SQL 修漏洞。每一步都有踩坑,也有解法。

第一步:让 AI Agent 能读我的邮件
Hermes 内置了一个叫 Himalaya 的终端邮件客户端,走 IMAP / SMTP 协议。Gmail 支持 IMAP,配好就能用。
但这里有个关键前提:我在国内,Gmail 的 IMAP 服务器被墙了。系统配了 SOCKS5 代理在 127.0.0.1:10808,但 Himalaya 是个 Rust 写的二进制工具,它的 TLS 库不走 macOS 系统代理。
配好配置后第一次运行:
himalaya folder list# Error: Connection reset by peer (os error 54)TCP 能通(nc -zv imap.gmail.com 993 成功),但 TLS 握手直接被 reset。折腾了几轮发现根因:Himalaya 直连不走代理。
解决方案是 proxychains-ng,一个通过 LD_PRELOAD 劫持网络调用的工具:
brew install proxychains-ng# 编辑 /usr/local/etc/proxychains.conf,把默认的 Tor 代理改成:# socks5 127.0.0.1 10808之后所有 Himlaya 命令加 proxychains4 前缀:
proxychains4 himalaya folder list| NAME | DESC ||--------------------|----------------------------|| INBOX | \HasNoChildren || [Gmail]/垃圾邮件 | \HasNoChildren, \Junk || [Gmail]/已删除邮件 | \HasNoChildren, \Trash || [Gmail]/已发邮件 | \HasNoChildren, \Sent || [Gmail]/草稿 | \Drafts, \HasNoChildren |通了。Gmail 文件夹是中文的,配置里文件夹别名也得用中文,不然发件箱保存会失败 —— 这是 Himlaya v1.2.0 的一个坑,别名必须用复数 folder.aliases,单数 folder.alias 会被静默忽略。
密码存 macOS Keychain,别写明文:
security add-generic-password -a "your-email@gmail.com" -s "himalaya-gmail" -w "your-app-password" -U
第二步:AI 读邮件,定位问题
接入之后,让 AI 搜 Supabase 相关的邮件:
proxychains4 himalaya envelope list --page-size 20 subject supabase搜出 20 封,最相关的两封:
- OpenRouter 通知「Supabase 从子处理器名单移除」—— 例行合规通知,跟安全无关,可以忽略
- Supabase 6 月 23 号的告警邮件 —— 正是我们要处理的
读邮件内容:
proxychains4 himalaya message read 11763邮件里列了 2 条 Critical 问题:
- 表被公开暴露 — RLS(Row Level Security)没开,任何人拿到项目 URL 就能读写数据
- 敏感数据公开暴露 — 某张表包含疑似密码、个人信息等字段,通过 API 无限制暴露
两种问题都指向同一个项目:umami-v2。
第三步:登录 Supabase,深入排查
让 AI 打开 Supabase Security Advisor 面板。登录走 GitHub OAuth——Hermes 的浏览器工具能自动填表。
但 GitHub 开了两步验证。TOTP 存在 Bitwarden 里,Bitwarden 又锁着。解法是直接从之前的 Bitwarden 导出 JSON 里提 TOTP secret,用 Python 算验证码:
import hmac, hashlib, base64, struct, time
secret = "XXXXXXXXXXXXXXX" # 从 Bitwarden 导出中提取secret = secret + "=" * (8 - len(secret) % 8)key = base64.b32decode(secret)counter = int(time.time()) // 30msg = struct.pack(">Q", counter)h = hmac.new(key, msg, hashlib.sha1).digest()offset = h[-1] & 0x0fcode = (struct.unpack(">I", h[offset:offset+4])[0] & 0x7fffffff) % 1000000print(f"{code:06d}") # 6 位 TOTP登录成功后,Security Advisor 显示:
Errors: 5 Warnings: 0 Info: 145 条 Error 详细拆解:
| 问题类型 | 涉及表 | 严重性 |
|---|---|---|
| RLS Disabled in Public | public.share | Error |
| RLS Disabled in Public | public.board | Error |
| RLS Disabled in Public | public.session_replay | Error |
| RLS Disabled in Public | public.session_replay_saved | Error |
| Sensitive Columns Exposed | public.session_replay | Error |
最严重的是 session_replay—— 同时触发了 RLS 未启用和敏感字段暴露两个告警。这张表存的是网站会话回放数据,里面可能有用户行为记录,完全没人看守。

第四步:写 SQL,执行修复
问题很明确:4 张表没开 RLS,其中 1 张还有敏感字段。修复分两步:开 RLS、建访问策略。
但建策略要考虑业务 ——umami 是网站分析工具,它的埋点 JS 通过 Supabase 的 anon key 写入数据。如果开 RLS 后不给 anon INSERT 权限,埋点全挂。
最终 AI 生成的 SQL:
-- 1. 开启 RLSALTER TABLE public.share ENABLE ROW LEVEL SECURITY;ALTER TABLE public.board ENABLE ROW LEVEL SECURITY;ALTER TABLE public.session_replay ENABLE ROW LEVEL SECURITY;ALTER TABLE public.session_replay_saved ENABLE ROW LEVEL SECURITY;
-- 2. 建策略:anon 可写入(umami 埋点),authenticated 可读取(后台看数据)CREATE POLICY "anon_can_insert_share" ON public.share FOR INSERT TO anon WITH CHECK (true);CREATE POLICY "auth_can_select_share" ON public.share FOR SELECT TO authenticated USING (true);-- ... 其他三张表同理在 Supabase SQL Editor 里跑完,结果:Success。刷新 Security Advisor —— 5 条 Error 清零。
但多了 4 条 Warning:RLS Policy Always True。原因是 INSERT 策略的 WITH CHECK (true) 太宽松。不过这正是 umami 的正常需求 —— 匿名用户必须能写埋点数据。4 条 Warning 标记为「已知接受」。
修复前后对比:
| 状态 | 修复前 | 修复后 |
|---|---|---|
| Errors | 5 | 0 |
| Warnings | 0 | 4(已知接受) |
| 表安全性 | 4 张表裸奔 | 全部上锁 + 有策略控制 |

总结
AI Agent 做了这么几件事:接入 Gmail 读邮件,搜到 Supabase 告警并解读内容,通过 GitHub OAuth 登录 Supabase 看 Security Advisor,逐表分析问题,然后生成修复 SQL—— 建策略的时候还考虑到了 umami 的埋点需求不能断。执行、验证、标记残余风险。全程在终端和浏览器里,没动鼠标。
以前觉得 AI Agent 就是高级点的聊天机器人。这次让我改观了 —— 它能读你的邮件、登你的平台、分析你的安全问题、写 SQL 修漏洞。不是「聊着玩」,是真的在干活。
下次收到安全告警,你还会自己处理吗?