作者:Yao & Thinking & Pds 编辑:77
背景
随着 AI 大模型实盘交易竞赛的升温,越来越多的加密社区与开发者开始尝试以 AI 驱动的自动化交易,诸多开源方案也被快速投入使用。然而,这些项目中不乏安全隐患。

NOFX AI 是一款基于 DeepSeek/Qwen AI 的开源加密货币期货自动交易系统,支持 Binance、Hyperliquid 与 Aster DEX 等交易所。慢雾安全团队接到 @Endlessss20 提供的最初情报,怀疑该系统可能会导致交易所 API Key 等泄漏,遂对此展开安全分析。
开源地址:https://github.com/NoFxAiOS/nofx
漏洞成因分析
经过慢雾安全团队的深入分析,发现 NOFX AI 在不同 commit 版本中存在两类主要鉴权问题。
“零鉴权”漏洞版本
2025 年 10 月 31 日的提交 517d0caf6fb091235e56c27889170b53a16e4e6b(origin/main、origin/dev 等分支均包含)引入了“默认管理员模式”,该 commit 版本的管理员模式默认开启且中间件直接放行。
config.json.example:1-24 与数据库迁移脚本都把 admin_mode 设为 true,main.go:42-63 在读取后直接调用 auth.SetAdminMode(true)。

(Refer:https://github.com/NoFxAiOS/nofx/blob/517d0caf6fb091235e56c27889170b53a16e4e6b/config.json.example)

(Refer:https://github.com/NoFxAiOS/nofx/blob/517d0caf6fb091235e56c27889170b53a16e4e6b/config/database.go#L214)

(Refer:https://github.com/NoFxAiOS/nofx/blob/517d0caf6fb091235e56c27889170b53a16e4e6b/main.go#L42-63)
更关键的是,在代码 api/server.go#L799 可以看到,只要 auth.IsAdminMode() 为 true,中间件会直接 return,完全跳过了 Authorization 认证头的检查。

(Refer:https://github.com/NoFxAiOS/nofx/blob/517d0caf6fb091235e56c27889170b53a16e4e6b/api/server.go#L799)
因此在这个 commit 提交及之前,只要部署保持默认管理员模式,任何人都能直接访问 /api/exchanges,拿到全部交易所 API/私钥。
在这种模式下,所有受鉴权保护的 API 包括 /api/exchanges 都会按 “admin” 身份执行,因此任何人只需向公开的 API 发起 GET 请求就能拿到数据库中 ExchangeConfig 的完整内容。
ExchangeConfig 字段包括 api_key、secret_key、hyperliquid_wallet_addr 以及 aster_private_key,均为交易所登录密钥或私钥。也就是说,只要保持默认管理员模式,任何人都可直接访问 /api/exchanges 并获取全部交易所 API/私钥。这份 commit 的代码相当于将所有交易所密钥暴露在一个无需登录的 GET 接口上。

要求 Authorization 的版本
在 2025 年 11 月 5 日的提交 be768d91a3969b39741623c9507f3119e583eb16(PR #540 “Enable admin password in admin mode”) 中, 开发者移除了原先只要检测到 admin_mode 就直接放行不验证 Authorization 的逻辑。
需要注意的是该 commit 目前只在 dev 系列分支里(包括本地 dev 和 origin/dev 等)。origin/main 并没有包含这个提交。
authMiddleware 被改写为 api/server.go:1471-1511 的形式,必须携带 Authorization: Bearer <token> 才能进入受保护路由。若格式错误或 JWT 验证失败,会直接返回 401。

(Refer:https://github.com/NoFxAiOS/nofx/blob/be768d91a3969b39741623c9507f3119e583eb16/api/server.go#L1471)
同一提交还新增了 /api/admin-login,要求部署者设置环境变量 NOFX_ADMIN_PASSWORD,也就是管理员模式不再是“无需登录自动生效”。如果 admin_mode 还是 true,main.go:203-226 会检查环境变量 NOFX_ADMIN_PASSWORD,并调用 log.Fatalf 直接终止进程,除非事先设置了该变量。设置完成后,管理员必须通过新的 /api/admin-login 接口提交这个密码才能拿到 JWT;没设密码就启动,会在初始化阶段被强制退出。

不过,这次改动只是把“完全无鉴权”升级为“必须提供 JWT”,仍然没有解决两个核心问题。
一是 config.json.example:1-27 依旧写死 jwt_secret,main.go:203-214 在环境变量缺失时继续回退到那个公开字符串。
若开发者直接使用示例配置文件,将导致默认密钥被启用,从而存在安全风险。而项目中的的默认部署脚本 start.sh 文件在检测到缺失配置时,会直接复制示例配置文件来使用。

二是 /api/exchanges 仍然以 JSON 形式把 api_key、secret_key、Aster 私钥等敏感字段原样返回。
因此,该版本访问 /api/exchanges 虽需 Authorization,但攻击者仍可通过默认密钥创建 JWT 或调用默认登录接口获取 token,从而读取全部密钥。

当前版本固定 JWT 问题依旧存在
截至目前(2025 年 11 月 13 日左右),dev 分支的 HEAD 为 b2e4be91523dc606be8708ec6602fecbbb0c20ea(PR #546 “Feature/faq”)。慢雾安全团队重新 checkout 这份提交后核对发现:
authMiddleware 仍是 api/server.go:1471-1511 的实现,需要 Bearer token;
/api/exchanges 仍直接返回 ExchangeConfig(api/server.go:1009-1021);
config.json.example:1-27 和 main.go:198-226 依旧硬编码 admin_mode=true 与默认 jwt_secret。
因此,只要运维人员没有主动更换 jwt_secret 并关闭管理员模式,攻击者仍可利用公开密钥创建固定 JWT,进而访问 /api/exchanges 并获取所有交易所 API/私钥。换言之,2025-11-05 的修复仅仅把漏洞从“零鉴权”变成了“凭默认密钥鉴权”,问题的根源依然存在。
影响
我们根据程序特征,全网搜索,发现公网存在 1000+ 已经私有化部署并且对外开放的系统:


慢雾安全团队意识到,随时可能出现攻击情况,第一时间全盘考虑安全方案,最终我们决定联系币安安全团队、OKX 安全团队,慢雾与币安、OKX 成立安全作战室,我们提供情报、影响范围,币安安全团队、OKX 安全团队各自独立交叉验证,根据获得的 api_key 反向推进,从系统层面定位受影响用户,告知用户面临的安全风险,第一时间更换 api_key、secret_key 等信息,防止用户资产被对敲导致资损,保护用户资产安全。
截至 11 月 17 日,所有受影响的 CEX 用户均已完成通知,并已废弃相关密钥,用户资产处于安全状态。
对于少数 Aster、Hyperliquid 用户,慢雾与币安团队已尝试主动联系,但由于地址为去中心化钱包地址,我们无法直接触达具体用户。如您正在使用 Aster、Hyperliquid 的自动化交易系统,请及时检查并处理相关风险。
同时,我们将与 NOFX AI 团队沟通本次漏洞详情,并提供修复建议,协助其完善系统安全。
总结与建议
当下 AI 大模型量化项目正热,但多数开源实现仍处于早期阶段。部署这类新兴开源系统时,务必要先做充分的代码安全审计并强化风控措施,避免造成资金的损失。
综合上述分析,NOFX 项目虽经修复尝试,但核心问题仍未解决。任何部署 NOFX 项目的 commit 517d0caf 及更早版本(origin/main 目前仍停在这一代)都处于“无需 Authorization”状态,必须立即升级或手工关闭 admin 模式。
即便升级到 be768d9 或当前 HEAD,如果继续使用默认 jwt_secret,攻击者仍可以通过创建固定 Authorization 头拿到密钥。要彻底修复该漏洞,需要同时做到:
1. 随机化 JWT 密钥:启动时若发现 jwt_secret 与模板相同,拒绝运行;建议改为写入安全存储或密钥管理系统。
2. 禁用默认管理员模式:仅在显式配置时才允许 admin 模式,并要求强密码 + OTP;非 admin 模式下 /api/admin-login 应直接关闭。
3. 最小化 /api/exchanges 响应:默认只返回启用状态、测试网标志等非敏感字段;导出 API/私钥需单独接口并二次验证,且服务端对字段做脱敏或加密。
在开发团队完成这些修复之前,任何面向公网的部署都应视为高危。尤其是 origin/main 仍处于 517d0c 的“零鉴权”阶段,维护方需尽快同步最新代码并严格执行自定义密钥及接口加固策略。