作者复盘一次批准并执行 AI 生成迁移脚本后导致生产数据大量丢失的事故。备份命令因参数冲突失败,错误输出被丢弃,脚本仍继续执行删除和恢复操作。
2026 年 4 月,我丢失了体育赛事预测网站 zoustos.com 背后的大部分数据。没有人入侵,也没有硬盘损坏。一次经我批准的迁移,执行了 AI 编写的脚本,而我和 AI 都把一些并不成立的假设当成了事实。
我写软件大约 25 年了,如今主要用 Claude Code 开发。它是我合作过的最好的结对编程伙伴。也正因如此,这件事值得记下来:它出错时信心十足,我也是。
任务很普通:给生产数据库改名,再创建一份开发环境副本。批准的方案分为五个阶段:
Claude 为这五个阶段写了一份脚本。我运行了它。
第一阶段,备份。两条 mongodump 命令一执行就失败了:
Cannot specify different database in connection URI and command-line option
连接字符串指向 /admin?authSource=admin,而 --db 参数指定的是源数据库。这两者冲突。报错信息很清楚,却没人看到,因为脚本把 stderr 重定向到了 /dev/null。
第二阶段停止了应用。
第三阶段删除了一个旧的镜像数据库,这一步原本就在计划中;接着,脚本尝试从一份根本不存在的快照恢复数据。这一步也静默失败了。脚本仍然继续执行,因为它所经过的 SSH 封装没有把退出码传回来。
第四阶段把所有配置,包括服务器上的 .env、CI secret、本地凭据文件,都改成了新的数据库名称和新用户。可这两者都还不存在。
第五阶段重启了应用。身份验证失败。HTTP 502。
到这里,情况虽然糟糕,但还能挽救:原来的数据库还在,完好无损。
Claude 写了一份恢复脚本。它有同样的 mongodump 问题,输出也同样被丢弃,因此这次依然没有生成备份。最后一步,它对原来的生产数据库执行了 db.dropDatabase(),而那是唯一一份仍然完好的数据。执行前,没有任何检查来确认可用的备份是否存在。
脚本打印出 MIGRATION COMPLETE。
我对数据目录做了逐字节快照,并在副本上尝试运行 mongod --repair。太晚了:WiredTiger 已经完成清理。磁盘上的数据已经没了。
在排查还能救回什么时,Claude 说,最后一份完好的备份可以恢复“9.7 万场历史比赛”。
我让它核实。备份里只有 12,828 场。9.7 万这个数字来自一份数据盘点记录,而那次盘点是在这份备份生成的 12 天之后做的。相差的大约 8.4 万场比赛,是最后一次备份之后,通过付费体育数据 API 回填的。这些数据已经丢了。
几分钟后,它又说:“oplog 覆盖了 6 天。”直接查询后发现,这个数据库的 oplog 只覆盖大约 32 小时。同一台服务器上的另一个项目把更早的条目挤出去了。
我们恢复了最后一份完好的备份,这次加上了验证步骤;随后重放了 oplog 中仍然保留、值得恢复的操作:223 条比赛插入和 558 条更新。那几周里其余的数据都丢了。
这既是工具的责任,也是我的责任。方案是我批准的,而我没有追问:备份失败了,要怎么发现?Claude 做了它很擅长的事:迅速生成一份看起来合理的脚本,并信心十足地描述结果。安全检查没有明确由谁负责,所以一项也没做。
于是,我明确了这项职责。现在,这些规则就放在我所有项目的 CLAUDE.md 顶部。
脚本失败时,必须明确报错。 任何会改变状态的操作,都不能把错误输出送进 /dev/null。使用 set -euo pipefail。退出码必须穿过 SSH 和其他所有封装,完整传回来。备份阶段如果没有生成任何备份,脚本就必须停止。
没有经过验证的备份,就不能删除数据库。 “经过验证”意味着:有人在同一次会话中打开备份,统计其中的数据,并确认数量与即将销毁的数据一致。而且,无论在哪个环境,都必须获得明确批准。
没有查询结果,就不能报数字。 除非工具在同一轮交互中给出了结果,否则 AI 不能声称某个数量、时间范围或恢复预估。记忆不算,“应该还在”也不算。不知道,就说“我不知道”,然后去查。
“运行过了”需要两项检查。 一项是退出码,另一项是实际结果。Exit 0 不代表文件已经写入。
总共有十条规则。其余规则涉及 secret(secret 值曾出现在 AI 对话记录里,导致我不得不把所有凭据轮换了两遍)、发送邮件和付款这类不可逆操作,以及测试、版本管理和上线检查清单。
我已经把这些规则放到 GitHub 上,同时附上了我使用的 /security-scan 命令。它会审计代码、服务器和凭据,报告结果后就停止,绝不打印任何 secret 值。
👉 github.com/selaias/claude-guardrails
这些内容免费提供,采用 MIT 许可证。你可以把它们复制到自己的 CLAUDE.md 中,再按实际情况修改。这些是指令,不是沙箱:你仍然需要真正的备份、切实的权限控制,以及让人类把关所有无法撤销的操作。
如果其中某条规则帮过你,或者你认为某条规则有问题,欢迎提 issue。我很想听听。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。