SayCraft 安全审查:七轮 Review、一次翻车、一个越权 Agent

我花了大概两周时间,对 SayCraft 做了一轮比较彻底的安全审查。七轮 code review,外加计费模块审计、死代码清理、一次上线翻车、一次 AI agent 越权。记录下来,给自己留个底。

七轮 Review 挖出来的东西

第一轮扫完我就知道事情不小。五个会议变更类路由,零所有权校验。只要拿到一个 meetingId,谁都能操作别人的会议——改计划、删内容、推状态,全开放。这不是边缘 case,是主干逻辑裸奔。

沙箱文件接口的问题更隐蔽。用户传入的路径直接拼接,看起来做了基本的 ../ 过滤,但 null byte、r、n 这些控制字符没拦。路径穿越的经典变种。

CORS 配置是另一个坑。Methods 和 Headers 无条件反射请求值,等于把浏览器的同源策略架空了。WebSocket 的 status 检查跑在 owner 校验前面,意味着攻击者可以枚举哪些 meetingId 是存在的。还有五个 module-level Map 从来没有清理逻辑,长时间运行下去就是内存泄漏。

这些问题单独看都不复杂,但它们同时存在,说明安全从一开始就没有被当作系统性的事情来做。

Owner Check 上线翻车

Review 完我很快加上了所有权校验。后端改好,测试通过,部署上线。

然后生产环境全面 break。

原因很蠢:前端 api.ts 里所有相关接口都没传 userId。后端加了校验,前端没跟上,请求全部被拒绝。不是某个功能不可用,是整个会议流程瘫痪。紧急回退。

教训很直接——后端安全加固不能只盯后端。校验逻辑和调用链必须一起过,一起测,一起上。听起来是常识,但在 review 的兴奋劲里,我确实只关注了"堵住漏洞",没想过"堵住之后前端还能不能正常调用"。

Agent 越权删代码

这件事发生在一个法律文件项目里。我起了一个多 agent workflow,其中有个"代码事实审计"agent,职责定义得很清楚:读代码,收集事实,输出报告。只读。

结果它发了 29 个 Edit 调用,跨 10 个文件,把 Alipay 支付模块从整个技术栈里删了。路由、服务层、配置项、类型定义,全删干净。一个审计 agent,自己判定 Alipay 集成"不完整",然后动手清理了。

问题出在工具权限。agent 的 prompt 说的是"只读审计",但它实际拥有 Edit 工具的调用权限。Prompt 是建议,工具权限才是硬约束。审计类 agent 绝不应该有写权限,无论 prompt 怎么写。这和人类组织里的道理一样:审计员不能有修改账本的权限。

计费模块:装饰性安全

计费审计是最让我哭笑不得的部分。

spendCredits() 函数写得很完整,逻辑清晰,有事务保护。问题是:零调用者。整个代码库没有任何地方调用它。用户看到的积分余额是纯展示,从未被实际消费。功能存在但从未接入,比没有更危险——它给人一种"已经做了"的错觉。

数据库层面也有问题。有个查询对 SUM 聚合加了 FOR UPDATE 行锁,PostgreSQL 不允许这个组合,运行时必报错。这意味着这段代码从来没被真正执行过,否则早就炸了。

鉴权就更直白了。所有 /billing/ 接口仅凭 x-user-id 这个 HTTP header 来识别用户身份。Header 可以随意伪造。没有 token 校验,没有签名,什么都没有。

死代码分析:两轮才靠谱

我先用 refactor-cleaner agent 做了一轮全量扫描,标准是"零外部调用者"。它找到 67 处可疑的死代码。数字很好看。

然后我用 code-reviewer agent 做二次验证,结论被大量推翻。很多函数在同文件内部有调用,只是没有跨文件导出。有些函数有完整的测试覆盖,说明是有意保留的公共接口。还有些是框架约定的生命周期钩子,不会被显式调用但运行时会触发。

"零外部调用者"不等于死代码。这个判定标准太粗了。单一 agent 的分析结论不能直接采信,必须经过独立的二次验证。

AI Code Review 的边界在哪

做完这一整轮,我对 AI code review 的认知变了不少。

它很擅长文本层面的模式匹配——缺少校验、可疑的拼接、不一致的错误处理,扫得又快又全。但文本审查不等于运行时验证。CORS 的实际行为取决于浏览器实现,WebSocket 的握手流程有协议层面的约束,这些东西不跑真实客户端是看不出来的。

Sub-agent 的结论必须交叉验证,这一点我反复踩坑才真正接受。第一个 agent 说"这是死代码",第二个 agent 可能说"不是,它在测试里被调用了"。两个结论都合理,但只有一个是对的。

还有一个倾向性问题:AI review 容易"看到问题就修"。它识别出一个风险点,下一步就想直接改掉,不会自动考虑修复对其他组件的连锁影响。Owner check 翻车就是这个模式的现实版本——漏洞堵上了,但调用方断了。

安全审查不是一次性的扫描任务。它是一个需要多视角、多轮次、带真实验证的持续过程。AI 工具在里面的定位是高效的第一遍筛查,但最终的判断和验证责任还是在人身上。

SayCraft 正在公测:saycraft.ai

感谢您的收看 祝你天天开心~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇