Background

With the rising competition in real trading of AI large models, more and more crypto communities and developers are starting to try AI-driven automated trading, and many open-source solutions are being rapidly put to use. However, these projects are not without security risks.

NOFX AI is an open-source cryptocurrency futures automated 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 this system might lead to leaks of exchange API Keys, so a security analysis was conducted.

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

Vulnerability Cause Analysis

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

'Zero authentication' vulnerability version

The commit on October 31, 2025, 517d0caf6fb091235e56c27889170b53a16e4e6b (branches such as origin/main, origin/dev, etc. all include this) introduced the 'default admin mode', where this commit version has admin mode enabled by default and the middleware directly allows access.

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

https://github.com/NoFxAiOS/nofx/blob/517d0caf6fb091235e56c27889170b53a16e4e6b/config.json.example
https://github.com/NoFxAiOS/nofx/blob/517d0caf6fb091235e56c27889170b53a16e4e6b/config/database.go#L214
https://github.com/NoFxAiOS/nofx/blob/517d0caf6fb091235e56c27889170b53a16e4e6b/main.go#L42-63

More critically, 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 check of the Authorization header.

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

Thus, in this commit and before, as long as the deployment maintains the default admin mode, anyone can directly access /api/exchanges to obtain all exchange API/private keys.

In this mode, all API requests protected by authentication, including /api/exchanges, will be executed as 'admin', so anyone only needs to make a GET request to the public API to obtain the complete contents of ExchangeConfig from the database.

The ExchangeConfig fields include api_key, secret_key, hyperliquid_wallet_addr, and aster_private_key, all of which are login keys or private keys for the exchange. This means that 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.

图片

Version requiring Authorization

In the commit 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 upon detecting admin_mode.

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 include this commit.

authMiddleware has been rewritten in the form of api/server.go:1471-1511 and must carry Authorization: Bearer <token> to enter protected routes. If the format is incorrect or JWT verification fails, it will directly return 401.

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

The same commit also added /api/admin-login, requiring deployers to set the environment variable NOFX_ADMIN_PASSWORD, meaning that 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, the administrator must submit this password through the new /api/admin-login interface to obtain the JWT; failing to set a password will result in being forcibly exited during the initialization phase.

However, this change only upgrades 'completely unauthenticated' to 'must provide JWT' and still does not resolve two core issues.

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

If the developer directly uses the example configuration file, it will lead to the default key being enabled, thus posing a security risk. The project's default deployment script start.sh will directly copy the example configuration file to use when it detects missing configurations.

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

Therefore, while this version requires Authorization to access /api/exchanges, attackers can still create JWTs with default keys or call the default login interface to obtain tokens, thus reading all keys.

图片

The fixed JWT issue still exists in the current version

As of now (around November 13, 2025), the HEAD of the dev branch is b2e4be91523dc606be8708ec6602fecbbb0c20ea (PR #546 'Feature/faq'). The SlowMist security team rechecked this commit and found that:

  • With the rising popularity of AI large model trading competitions, more and more crypto communities and developers are starting to experiment with AI-driven automated trading, and many open-source solutions are being rapidly put to use. However, these projects are not without security risks.
  • /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 the default jwt_secret.

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

Impact

Based on program features, we conducted a network-wide search and found over 1000 systems that have already been privatized and are open to the public:

The SlowMist security team realized that an attack could occur at any time, and immediately considered security solutions. Ultimately, we decided to contact the Binance security team and the OKX security team. SlowMist established a security operations center with Binance and OKX, providing intelligence and scope of impact. The Binance and OKX security teams each independently cross-verified, advancing from the obtained api_key to locate affected users from the system level, informing them of the security risks they face, and promptly replacing api_key, secret_key, and other information to prevent user assets from being harmed by market manipulation, thereby protecting user asset security.

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

For a few Aster and Hyperliquid users, SlowMist and the Binance team have attempted to proactively reach out, but since the address is a decentralized wallet address, we cannot directly contact specific users. If you are using Aster or Hyperliquid's automated trading system, please check and address the relevant risks promptly.

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

Summary and Recommendations

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

In summary, despite attempts to fix, the core issues of the NOFX project remain unresolved. Any deployment of NOFX project's commit 517d0caf and earlier versions (origin/main is currently still at this generation) is in a 'no Authorization' state and must be upgraded immediately or manually disable admin mode.

Even if upgraded to be768d9 or the current HEAD, if the default jwt_secret is still used, attackers can still obtain the key by creating a fixed Authorization header. To completely fix this vulnerability, it is necessary to achieve:

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

2. Disable default admin mode: Only allow admin mode when explicitly configured, and require strong passwords + OTP; non-admin mode should directly disable /api/admin-login.

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

Before the development team completes these fixes, any deployment facing the public network should be considered high-risk. Especially since origin/main is still in the 'zero authentication' stage of 517d0c, maintainers need to quickly sync the latest code and strictly enforce custom key and interface hardening strategies.

Acknowledgment

Thanks again to @Endlessss20 for providing the initial intelligence source!