Three-way Side by Side: NOFX AI Trading System Vulnerability Defense Battle

Author: Yao & Thinking & Pds Editor: 77

Background

With the rise of AI large model real-time trading competitions, more and more crypto communities and developers are beginning to experiment with AI-driven automated trading, and various open-source solutions are being quickly put into use. However, these projects are not without security risks.

NOFX AI is an open-source cryptocurrency futures trading system based on DeepSeek/Qwen AI, supporting exchanges such as Binance, Hyperliquid, and Aster DEX. The SlowMist security team received initial intelligence from @Endlessss20, suspecting that the system could lead to leaks of exchange API Keys, and thus conducted a security analysis.

Open source address: https://github.com/NoFxAiOS/nofx

Vulnerability Cause Analysis

After in-depth analysis by the Slow Fog security team, it was found that NOFX AI has two main authentication issues across different commit versions.

“Zero Authentication” Vulnerability Version

The submission on October 31, 2025, 517d0caf6fb091235e56c27889170b53a16e4e6b (including branches such as origin/main, origin/dev, etc.) introduced the “default admin mode,” which is enabled by default in this commit version and allows middleware to pass through directly.

config.json.example:1-24 sets admin_mode to true along with the database migration script, and main.go:42-63 directly calls auth.SetAdminMode(true) after reading.

(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)

More importantly, in the code api/server.go#L799, it can be seen that as long as auth.IsAdminMode() is true, the middleware will directly return, completely skipping the Authorization header check.

(Refer: https://github.com/NoFxAiOS/nofx/blob/517d0caf6fb091235e56c27889170b53a16e4e6b/api/server.go#L799)

Therefore, in this commit and before, as long as the deployment remains in default administrator mode, anyone can directly access /api/exchanges and obtain all exchange API/private keys.

In this mode, all authenticated APIs, including /api/exchanges, will execute under the “admin” identity, so anyone can obtain the complete content of ExchangeConfig in the database by simply making a GET request to the public API.

The ExchangeConfig fields include api_key, secret_key, hyperliquid_wallet_addr, and aster_private_key, all of which are exchange login keys or private keys. In other words, as long as the default admin mode is maintained, anyone can directly access /api/exchanges and obtain all exchange API/private keys. This commit's code is equivalent to exposing all exchange keys on a GET interface that does not require login.

Required version of Authorization

In the submission on November 5, 2025, be768d91a3969b39741623c9507f3119e583eb16( PR #540 “Enable admin password in admin mode”), the developer removed the logic that previously allowed direct access without verifying Authorization as long as admin_mode was detected.

It should be noted that this commit is currently only in the dev series branches (including local dev and origin/dev, etc.). origin/main does not contain this commit.

authMiddleware has been rewritten in the form of api/server.go:1471-1511 and must carry Authorization: Bearer to access protected routes. If the format is incorrect or JWT verification fails, a 401 will be returned directly.

(Refer:https://github.com/NoFxAiOS/nofx/blob/be768d91a3969b39741623c9507f3119e583eb16/api/server.go#L1471)

The same submission also added /api/admin-login, requiring the deployer to set the environment variable NOFX_ADMIN_PASSWORD, meaning that the admin mode is no longer “automatically effective without login.” If admin_mode is still true, main.go:203-226 will check the environment variable NOFX_ADMIN_PASSWORD and call log.Fatalf to terminate the process directly, unless this variable is set in advance. After setting it up, the administrator must submit this password through the new /api/admin-login interface to obtain the JWT; starting without setting a password will force an exit during the initialization phase.

However, this change only upgrades “completely unauthorized” to “must provide JWT”, still not addressing the two core issues.

First is config.json.example:1-27 still hardcodes jwt_secret, main.go:203-214 continues to fall back to that public string when the environment variable is missing.

If developers directly use the sample configuration file, the default key will be enabled, which poses a security risk. The default deployment script start.sh in the project will directly copy the sample configuration file for use when it detects a missing configuration.

Secondly, /api/exchanges still returns sensitive fields such as api_key, secret_key, and Aster private key in JSON format as they are.

Therefore, this version accesses /api/exchanges which requires Authorization, but attackers can still create JWTs using the default key or call the default login interface to obtain a token, thereby reading all keys.

The fixed JWT issue in the current version still exists

As of now (around November 13, 2025), the HEAD of the dev branch is b2e4be91523dc606be8708ec6602fecbbb0c20ea (PR #546 “Feature/faq”). The Slow Mist security team re-checked this commit after checking out.

  • authMiddleware is still the implementation in api/server.go:1471-1511, requires Bearer token;
  • /api/exchanges still directly returns ExchangeConfig (api/server.go:1009-1021);
  • config.json.example:1-27 and main.go:198-226 still hardcode admin_mode=true and default jwt_secret.

Therefore, as long as the operation and maintenance personnel do not actively change the jwt_secret and disable the admin mode, attackers can still use the public key to create fixed JWTs, thereby accessing /api/exchanges and obtaining all exchange API/private keys. In other words, the fix on 2025-11-05 merely changed the vulnerability from “zero authentication” to “authentication with default keys”; the root of the problem still exists.

Influence

We conducted a network-wide search based on program characteristics and found that there are over 1000 systems that have been privatized and are open to the public:

The Slow Mist Security Team is aware that an attack situation may occur at any time. We comprehensively considered security solutions at the first moment and ultimately decided to contact the Binance Security Team and the OKX Security Team. Slow Mist, Binance, and OKX established a security command center. We provided intelligence and the scope of impact. The Binance Security Team and the OKX Security Team independently cross-verified and pushed forward based on the obtained api_key, locating affected users from the system level, informing users of the security risks they face, promptly changing api_key, secret_key, and other information to prevent users' assets from being lost due to counter-trading, thereby protecting users' asset security.

As of November 17, all affected CEX users have been notified and have discarded the relevant keys, ensuring that user assets are in a secure state.

For a small number of Aster**, Hyperliquid** users, Slow Mist and the Binance team have attempted to proactively reach out, but since the addresses are decentralized wallet addresses, we cannot directly contact specific users. If you are using the automated trading systems of Aster, Hyperliquid, please check and manage the related risks in a timely manner.

At the same time, we will communicate the details of this vulnerability with the NOFX AI team and provide repair suggestions to assist them in improving system security.

Summary and Recommendations

Currently, AI large model quantization projects are gaining popularity, but most open-source implementations are still in the early stages. When deploying such emerging open-source systems, it is essential to conduct thorough code security audits and strengthen risk control measures to avoid financial losses.

In summary, despite the attempts to fix the NOFX project, the core issues remain unresolved. Any deployment of the NOFX project with commit 517d0caf or earlier versions (origin/main is still at this generation) is in a “No Authorization Required” state and must be upgraded immediately or manually shut down admin mode.

Even if upgraded to be768d9 or the current HEAD, if the default jwt_secret is still used, an attacker can still obtain the key by creating a fixed Authorization header. To completely fix this vulnerability, the following must be done simultaneously:

  1. Randomize JWT secret: If jwt_secret is found to be the same as the template at startup, refuse to run; it is recommended to write it to a secure storage or key management system.

  2. Disable default admin mode: Allow admin mode only when explicitly configured, and require a strong password + OTP; the /api/admin-login should be directly closed in non-admin mode.

  3. Minimize /api/exchanges response: By default, only non-sensitive fields such as enabled status, testnet flag, etc., are returned; exporting API/private keys requires a separate interface and secondary verification, and the server should desensitize or encrypt the fields.

Any deployment facing the public network should be considered high risk until the development team completes these fixes. Especially since origin/main is still in the “zero-authentication” phase at 517d0c, the maintainers need to synchronize the latest code as soon as possible and strictly implement custom key and interface hardening strategies.

View Original
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Reward
  • Comment
  • Repost
  • Share
Comment
0/400
No comments
  • Pin

Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate App
Community
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)