OpenAI 与 Hacktron 达成合作,查找其系统中的漏洞。阅读公告。

跳到正文 Hacktron 登录 [S]
Hacktron 登录 [S] 客户案例 博客 文档 联系我们 登录

Novu 要的是信心,不是更多流程


Novu
Hacktron Review

, , X, LinkedIn

分享

Novu 要的是信心,不是更多流程

XLinkedIn
2分钟
修复 28 个安全问题
前 30 天内
83% 的问题
需要处理,不是噪音
NoSQL 注入
其他工具都漏掉了

“就像有个渗透测试工程师在审你提的每一个 PR。”

Dima Grossman
首席技术官

关于 Novu

Novu 是一个开源的通知基础设施平台:一套 API 就能通过 15 个以上的渠道(应用内、邮件、短信、推送)发送通知,支持云端部署,也支持物理隔离的私有化部署。开源版本在 GitHub 上有 39,000 个 Star 和 400 多名外部贡献者。Novu 正通过 Novu Connect 拓展双向 Agent 通信,让 AI Agent 直接在 Slack 等渠道中完成任务,而不只是把用户引到别处。

挑战:400 名贡献者参与的代码库,怎么放心

Novu 对每一项外部贡献都执行零信任策略。外部贡献者超过 400 名,任何代码不经严格审查都不能发布。眼下两件事同时发生:AI 让 Novu 交付的代码越来越多,团队也越来越怀疑,为合规而做的第三方安全评估到底能发现什么。

“每年的第三方评估做得越多,我就越不信任它们。他们对所有客户都套同一份十项检查清单,查出来的通常都是些无关紧要的东西。

“该打的勾是打上了,但我们内部根本不信这一套。”

Dima Grossman
首席技术官

Novu 已经有一套分层工具(CodeQL、Greptile、Cursor 的安全审查工具,以及定期的 DeepSec 扫描),在两个节点运行:每次提交 PR 时跑一遍,发版打 tag 前再跑一遍。

“有了 AI,我们在产品面上的产出多了很多。

“审查时人为出错的概率自然也高了很多。”

Dima Grossman
首席技术官

解决方案:流程不变,信心更足

哪些变了、哪些没变,Dima 说得很直接:

“用了 Hacktron,我们的流程一点没变。真正变的只有信心:我们知道自己能抓到复杂得多的漏洞模式。

“有了这份信心,我们也能把速度提上去。”

Dima Grossman
首席技术官

这份信心,说到底来自信号质量。Novu 现有的工具大多只能标出 PR diff 里看得见的问题(Dima 称之为“单跳”利用)。Hacktron 会为仓库构建代码图,并在 PR 之间对比代码图的差异,找出二阶问题:只有追踪一个文件的改动如何影响系统其他位置的代码,这类漏洞才会显现。

“其他工具的评论,很多时候要么不在范围内,要么属于可接受的风险。

“Hacktron 报出来的,团队会认真看、仔细想。很多时候确实很有价值。”

Dima Grossman
首席技术官

Dima 还点出了他一直在防范的风险:噪音疲劳。

“谁都不想让它变成天天喊狼来了的工具。

“报告里通知太多,看着看着就抓不住重点了。”

Dima Grossman
首席技术官

在这里,信号质量不是锦上添花,它决定了团队会认真看这个工具,还是学会无视它。

问题分析

Novu 使用 Hacktron 的前 30 天(2026 年 7 月 6 日至 8 月 6 日):

230 个 PR61 个问题中已分类处理 42 个28 个已解决1 个真实漏洞6 个已接受风险7 个误报 230 个 PR61 个问题中已分类处理 42 个28 个已解决1 个真实漏洞6 个已接受风险7 个误报

另有 18 个问题仍待分类处理,还有 1 个因对应的 PR 被放弃而撤回。

能发现哪些漏洞?

Novu 自己的工具大多只能发现单个文件或单个 PR diff 里看得见的问题。Dima 特别看重的,是那些必须跨多个文件追踪调用才能发现的漏洞,而这恰恰是模式匹配扫描器无从标记的。

NoSQL 注入与跨对话越权(高危)

在 PR #12062 中发现,合并前已在同一 PR 中修复。

当时 Novu 正在上线一条新的数据接入链路,让自托管的 AI Agent 向平台发送结构化事件(消息、回复、审批)。链路中有一步需要根据客户端传入的消息 ID,把收到的事件匹配回对应的对话活动:

private async resolveActivityByClientId(
environmentId: string,
conversationId: string,
messageId: string
): Promise<ConversationActivityEntity | null> {
for (let attempt = 0; attempt < ACTIVITY_RESOLVE_MAX_ATTEMPTS; attempt += 1) {
const activity = await this.activityRepository.findOne(
{ _environmentId: environmentId, identifier: messageId },
'*'
);
if (activity) {
return activity;
}
if (attempt < ACTIVITY_RESOLVE_MAX_ATTEMPTS - 1) {
await delay(ACTIVITY_RESOLVE_DELAY_MS);
}
}
return this.activityRepository.findByPlatformMessageId(environmentId, conversationId, messageId);
}

这里有两个问题叠加。第一,查询条件只校验了环境,没有校验活动属于哪个对话。第二,传入的 messageId 直接用进了查询条件,事先没有校验它是不是普通字符串,因此可以被换成 MongoDB 查询操作符,而不是 ID。两者叠加,已认证的调用方就能解析出不属于自己的对话中的活动,进而编辑或删除。

Hacktron Review 追踪了横跨三个文件的调用链,发现了这个问题:接收原始事件载荷的接入控制器,不做深度校验就把载荷转成类型化事件的用例,以及把未校验的 ID 传进上述查询的 sink 服务。

成效:信心足了,交付反而更快

400 多名外部贡献者参与的代码库,如今有了持续审查。没有让团队对安全工具视而不见的噪音疲劳,Novu 也更有信心,交付不降速,反而更快。

客户案例

联系我们

预约演示或免费试用。

[↓] [↑] 按 [enter] 打开
菜单
[M]
菜单下一项
[J]
菜单上一项
[K]
搜索
[F]
提问
[A]
登录
[S]
复制页面
[C]
收听
[L]
两端对齐
[R]
语言
[G]
深色模式
[D]
高对比度
[H]
快捷键
[I]
关闭
[Esc]