昨天,我的自研 GTD 系统后台突然多了 5000 多个新增账号,actions 也陡增了 3000 多条。
第一反应当然是:难道产品突然爆火了? 几分钟之后我冷静下来:这更像是一场「恶意注册 / 接口攻击」,而不是增长奇迹。
这篇文章想简单记录一下:
- 这次攻击是怎么暴露出来的
- 我是怎么用 Claude Code 快速排查问题的
- 我对「小产品的安全边界」的几个反思
希望能给同样在做小产品 / side project 的同学一点参考:就算你现在只有几十个真用户,也值得认真对待安全和风控。
一、事情是怎么被发现的?
先简单说一下背景。 我用 Claude Code 搭了一套自己的 GTD 系统,名字叫 GTD Pro,灵感来自 OmniFocus ,目前主要是我自己和少量真实用户在用,线上版本在这里: https://gtd.nebulame.com/
按照正常节奏,这个系统一天新增用户只有几个人,有时候甚至是 0 。结果昨天我在后台看统计时,发现:
- 账号总数在很短时间里突然多了 5000+ 个
- actions 表里多了 3000+ 条明显无效的数据
问题在于:
- 我并没有做任何大规模推广
- 真实的活跃用户,其实只有几十个
所以这波「暴涨」明显不正常。
我简单做了几件事:
- 按时间排序,发现这些账号几乎集中在一个很短的时间窗口内创建
- 看标识/行为,很多请求模式非常机械、重复
- 对比真实用户的使用行为,路径和频率完全不一样
基本可以确认:这是一次针对后端 API 的「恶意注册 + 写入」攻击,而不是自然增长。
二、这次攻击到底发生了什么?(攻击情况一览)
从日志里复盘了一下,大概情况是这样的:
- 攻击开始时间:2025-12-30 00:28 左右
- 持续时间:从 00:28 一直持续到 05:07 左右
- 攻击方式:不停地往两个接口打请求:
POST /api/auth/register 注册接口被高频调用 POST /api/inbox Inbox 创建接口被高频调用
几小时之内,数据变成了这样:
- 用户数:从 38 个涨到 5512 个(+5474 个恶意账号)
- Actions:从 119 条涨到 3209 条(+3090 条无效记录)
- 数据库大小:从大约 400KB 涨到 12MB 左右(体积直接放大了 30 倍)
从时间分布和请求模式看,很明显这不是正常用户增长,而是脚本在持续轰炸注册接口和 Inbox 接口。这里可以放上 Claude Code 帮我整理出来的攻击摘要和时间线截图,我也是在它的提示下,开始给系统补上第一轮安全防护。
三、我和 Claude Code 做了一次「线上演习」
这次排查其实花的不是很多精力,更多是靠 Claude Code 帮我把问题结构化了一遍。
大概流程是这样:
- 我把相关的日志片段、数据特征、接口设计,整理成一个简化版描述
- 丢给 Claude Code ,让它帮我:
- 分析可能的攻击路径
- 提出优先级最高的几条防护建议
- Review 一下现有的注册 / 写入接口设计
Claude 给出的几个方向非常实用:
- 后端 API 暴露在公网,没有最基本的 rate limit
- 注册和写入接口缺少「人类门槛」,脚本可以无限请求
- 没有给「可疑账号」打标 / 隔离,只是直接进入正式业务表
我对照这些建议,很快做了第一轮处置:
- 给这批可疑账号和对应 actions 打上标记,而不是直接物理删除
- 在业务逻辑上先软删除:统计、报表、产品逻辑里一律不算它们
- 开始在代码里补上 rate limit 和简单风控策略
这次体验对我来说有点意思:
- 不是「 AI 帮我写了一大堆代码」,而是
- 「 AI 帮我快速梳理威胁模型 + 设计第一版防护方案」,我自己做关键决策和实现细节
对一个只有几十个真实用户的小产品来说,这种「 AI + 人」的协作方式刚好合适。
四、我给 GTD 系统加了三道基础安全锁
这次事件之后,我给 GTD Pro 加了三道「基础安全锁」,也推荐给还在早期的独立开发者:
1 )给注册和写入接口上闸门
- 对注册接口加简单节流:同 IP / 同 UA / 同邮箱域名在单位时间的上限
- 对写 actions 的接口也加上 rate limit ,避免有人用单一账号或脚本刷爆写入
2 )引入一个「人类门槛」
- 可以是邮箱验证 / 一次性验证码 / 极简验证码
- 不一定要很重,但要让大规模脚本攻击的成本变高
3 )业务上把「可疑流量」和「真实用户」彻底分开
- 给这 5000 多个账号统一打上
is_suspicious = true - 统计和报表默认只看「未标记为可疑」的账号
- 以后如果还有类似事件,可以快速对比行为模式、复用处理流程
这次攻击也间接帮我确立了一个心态:
- 只要你的产品暴露在公网,就默认会被扫、被撞、被试探
- 安全不是「有大公司再做」,而是「你第一次被攻击的那天,就该开始认真设计」
五、小产品也要有安全边界
这次恶意注册事件,对我最大的提醒是:
- 就算你现在只有几十个真实用户,也应该早点想好:
- 注册/登录的边界
- 写入数据的节流
- 垃圾数据的隔离策略
- AI 不只是用来给用户做「炫酷功能」,也可以拿来帮你做基础设施:
- 设计威胁模型
- 帮你 review 代码
- 帮你想「最小代价的安全升级」
严格来说,这次并不能算一场「大规模攻击」,更像是给我提了个醒:
- 我的 GTD 不再只是本地小玩具
- 它开始作为一个真正对外的在线服务存在
六、如果你也想试试这套 GTD / 看看代码
最后,留两个入口:
如果你也在做自己的小工具、小产品,建议不要等到「出事了」再补安全。哪怕只是在注册接口前面多加几行简单的 rate limit 逻辑,都是一个好的开始。
也欢迎你来试试 GTD Pro ,或者在 issue 里告诉我你遇到的安全/风控问题,我们可以一起继续把这套系统打磨得更像一个真正可依赖的「第二大脑」。
如果你对我在做的通用 Agent 框架也感兴趣,可以看看:
GTD Pro 目前主要跑在 Claude Code 上,后面也会逐步和这套 Agent 基础设施打通。