Hacktron 如何为 Rocket.Chat 提供全天候安全保障
- 平均 1–2 分钟
- 完成一个 PR 的安全审查
- 17 个真实漏洞
- 在最初 20 天内发现并分诊
- 73% 的已发现问题
- 需要处理并已得到处理
“现在我们能把安全扫描扩展到所有 PR 上。
“Hacktron 会标记潜在问题,让我们把审查精力集中在更需要关注的拉取请求上。”
Julio Araujo
安全总监
关于 Rocket.Chat
Rocket.Chat 是一个开源、可完全自定义的通信平台,全球的政府、国防和企业团队都在使用它。对于这样规模的软件来说,安全是重中之重,而发现安全漏洞成本最低的阶段之一是软件开发生命周期的早期,即在代码进入生产环境之前,通过更好的设计和持续的代码审查来发现。
挑战:代码速度与安全审查之间的差距日益扩大
然而,即使在 AI 出现之前,开发人员与安全工程师的人数比例就已让逐一细致审查每个 PR 中的漏洞变得不切实际。如今 AI 正在加快代码的编写和交付速度,对每次改动进行安全审查比以往任何时候都更加重要。
“我们根本没有足够的工程师对每个 PR 进行彻底审查。传统的 SAST、SCA 和密钥扫描工具可能非常有用,我们也仍在使用,但它们往往缺乏识别业务逻辑漏洞等复杂问题所需的上下文。
“它们也难以进行多步推理,或把漏洞串联起来,从而理解一个系统实际上会如何被利用。”
Julio Araujo
安全总监
借助 Hacktron 将安全审查扩展到每个 PR
为弥合这一差距,Rocket.Chat 使用 Hacktron Review 进行持续、全天候的代码和安全审查,帮助在代码进入生产环境之前发现代价高昂的漏洞。
对于每个 PR,Hacktron 会:
- 对代码改动进行深度安全审查。
- 直接在 PR 中以清晰的评论标记漏洞。
- 让开发人员在合并前修复需要处理的问题。
- 帮助安全团队跟踪较低优先级的发现,并分批定期修复。
- 让安全审查持续进行,而不只是依赖定期审计或人工审查。
“Hacktron 会随着时间推移从我们的代码库和反馈中学习。
“随着我们提供更多关于预期功能、已接受风险和安全要求的上下文,误报越来越少,准确性不断提高,花在分诊非问题上的时间也减少了。”
Julio Araujo
安全总监
下面我们来分析 Hacktron 在 Rocket.Chat 上的审查:它能发现哪些类型的漏洞、这些发现有多准确,以及它如何帮助团队更快交付。在最初 20 天里,它审查了 155 个 PR,发现了真实存在的问题。其中包括一个严重的授权漏洞,它本可让任何已登录用户下载其他用户的完整数据导出;两个严重的 Apple OAuth 缺陷,削弱了各个部署中的登录边界;以及几个 XSS 漏洞。
发现分析
在最初 20 天(2026 年 6 月 5 日至 25 日)里,Hacktron 在每个拉取请求提交时即对其进行审查,对 10,744 个改动文件运行了 490 次扫描。以下按已审查的 PR、发现的问题、分诊情况以及有效发现的实际严重程度分类统计。
每个 PR 都会被自动审查。对于一个典型的 PR,审查本身只需约 1–2 分钟(中位数为 1.4 分钟,第 95 百分位为 5.3 分钟),速度快到足以放进 CI 而不拖慢任何人。不过需要注意的是,如果一个 PR 的改动很多,Hacktron 会花更多时间,确保测试足够彻底。
它能发现哪些类型的漏洞?
那么,关键问题在于它发现了哪些类型的漏洞。Hacktron 不只是一个模式匹配器,它会像安全研究人员一样阅读并推理代码。因此,这些发现涵盖了 OWASP Top 10 的大部分类别:访问控制失效、认证/2FA 绕过、XSS、SSRF/开放重定向、加密机制失效、密钥泄露以及业务逻辑缺陷。
下面详细介绍 Hacktron 发现的前 3 个漏洞。
通过 Apple OAuth 接管账户
这是 Rocket.Chat 将 Hacktron 集成到工作流后,Hacktron 发现的第一个漏洞,也是一个非常精妙且严重的漏洞。
这里有一个重要细节:Hacktron 发现的漏洞位于 PR 改动之外。原因在于 Hacktron 的审查并不局限于 PR diff,它会在整个代码库中梳理依赖关系及其影响,从而发现二阶漏洞。
高危
Apple OAuth 登录中未经验证的邮箱导致账户接管
apps/
loginHandler.ts 中的 Apple OAuth 登录处理程序存在一个漏洞:当 Apple 身份令牌中不包含邮箱地址时,它会信任客户端提供的邮箱地址。由于 loginRequest 中客户端提供的 email 字段未经加密验证,攻击者可以提供任意邮箱地址(例如受害者的邮箱)。随后,accounts_meld.js 钩子会使用这个未经验证的邮箱查找现有用户,并将攻击者的 Apple 服务 ID 关联到受害者的账户。这使攻击者能够用自己的 Apple ID 登录受害者的账户,导致账户被完全接管。
复现步骤
- 攻击者使用自己的 Apple ID 发起 Apple 登录,并确保 Apple
identityToken中不包含email声明(例如使用未共享邮箱的 Apple ID,或在 Apple 省略邮箱的后续登录中)。 - 攻击者拦截发送到 Rocket.Chat 服务器的登录请求(例如 DDP
login方法调用)。 - 攻击者修改
loginRequest载荷,在email字段中填入受害者的邮箱地址:{"identityToken": "<attacker_token>", "email": "victim@example.com", "fullName": {...}}。 - 服务器处理该请求。在
loginHandler.ts中,serviceData.email为空,因此它执行serviceData.email = email(即受害者的邮箱)。 accounts_meld.js钩子按受害者的邮箱查找用户,找到受害者的账户,并将攻击者的 Apple ID 关联到该账户(Users.setServiceId(user._id, serviceName, serviceData.id))。- 攻击者现在已登录受害者的账户,并可随时使用自己的 Apple ID 访问该账户。
在 apps/meteor/app/apple/server/loginHandler.ts 中,当 Apple JWT 不包含邮箱时,Apple 登录流程会回退使用客户端提供的邮箱:
const serviceData = await handleIdentityToken(identityToken);if (!serviceData.email && email) { serviceData.email = email; // attacker-controlled fallback}攻击者可以伪造一个不含邮箱声明的 Apple JWT,并在请求中提供任意 email,从而以任意用户身份通过认证。由于该漏洞存在于原有代码中,Rocket.Chat 将其作为严重级别安全公告发布(GHSA-wx3c-76rf-wpwf,CVE-
Apple 登录跳过 JWT 声明验证
同一个处理程序中还有另一个漏洞:它验证了 JWT 签名,却跳过了声明验证。它使用的是 JWS.verify(仅验证签名),而不是 JWS.verifyJWT,并且从未检查 aud、exp 或 nbf。任何带有非空 iss 的 Apple 签名令牌都会被接受,因此泄露的令牌或面向其他受众的令牌可以被重放,以受害者身份登录,而且重放窗口没有过期时间。Rocket.Chat 将其作为高危级别安全公告发布(GHSA-c75c-5hc7-j4vp,CVE-
严重
Apple 身份令牌处理程序缺少 JWT 受众(aud)验证,导致账户接管
apps/meteor/app/apple/lib/handlePassportIdentityToken.ts 中的 handlePassportIdentityToken 函数负责在基于 Passport.js 的 Apple 登录流程(apps/meteor/app/apple/server/applePassportOAuth.ts)中解析和验证 Apple 身份令牌。它正确验证了令牌的加密签名、签发者(iss)和过期时间(exp),却没有验证受众(aud)声明。
在 OpenID Connect 等基于 JWT 的认证流程中,aud 声明表示令牌的预期接收方(即 Client ID)。如果不验证 aud 是否与 Rocket.Chat 实例配置的 Apple Client ID 一致,应用就会接受任何有效的 Apple 身份令牌。
攻击者可以创建自己的应用并启用“通过 Apple 登录”来利用这一点。当受害者登录攻击者的应用时,攻击者就会获得该受害者的有效 Apple 身份令牌。随后,攻击者可以将该令牌提交到 Rocket.Chat 服务器的 Apple OAuth 回调端点。由于该令牌确实由 Apple 签名、签发者有效且未过期,handlePassportIdentityToken 会返回受害者的数据。上游的 Passport 策略(applePassportOAuth.ts 中的 AppleStrategy)随后会使用这些数据让攻击者以受害者身份登录,导致账户被完全接管。
请注意,apps/meteor/app/apple/lib/handleIdentityToken.ts 中的另一个函数 handleIdentityToken 正确实现了受众验证,而 handlePassportIdentityToken 完全遗漏了这一步。
任何用户都能下载其他用户的数据导出
在 GDPR 数据导出的下载路径中,调用访问检查时没有传入文件对象,因此检查默认放行,授权给了任何已登录用户。只要有一个有效的导出文件 ID,攻击者就能获取其他用户的完整数据导出,包括私密消息、个人资料和房间数据。在 PR #40889 中发现,并在合并前修复。
严重
UserDataFiles 中的对象级授权失效(BOLA)使任何已认证用户都能下载 GDPR 数据导出
apps/
Rocket.Chat 的文件上传访问控制机制中存在一个授权绕过漏洞。当用户请求从 UserDataFiles 集合(其中包含用户高度敏感的 GDPR 数据导出,包括私密消息、私信和个人数据)下载文件时,服务器未能验证发起请求的用户是否为该数据导出的所有者。
成果:更强的安全态势,花在分诊非问题上的时间更少
对 Rocket.Chat 而言,最大的影响在于杠杆效应。Hacktron 让安全团队能够在整个开发工作流中一致地应用专家级审查,而不会让安全成为拖慢工程速度的阻碍。
结果是工程与安全之间形成了更紧密的反馈闭环:漏洞被更早发现,开发人员在改动发生时就能获得更清晰的指导,安全团队花在筛查噪音上的时间更少,能把更多时间投入真正重要的问题。