Back to skill

Security audit

Futu Client

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its Futu trading purpose, but it can place live trades by default without a separate confirmation step, creating real financial risk.

Install only if you understand that this skill can read brokerage account data and submit real orders through a running FutuOpenD session. Use SIMULATE explicitly, avoid sharing or logging trading passwords, and do not allow automated agents to call live trading methods without your own confirmation and order limits.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
skill.md:34
Finding

Unpinned Third-Party Trading Dependencies

Content
View full analysis

Vulnerability Details

File Location: skill.md:11 and skill.md:34-36
Vulnerability Type: T08: Insecure Dependencies
Risk Level: Medium

Vulnerable Code

markdown
- Install dependencies: `pip install futu-api`
bash
pip install futu-api pandas

Technical Analysis

The installation instructions retrieve futu-api, pandas, and their transitive dependencies without fixed versions or integrity hashes. Consequently, installation results depend on whichever package versions the configured package index serves at that time.

If a direct or transitive dependency is compromised, malicious code could be delivered without any modification to this project. Such code may execute through source-build installation hooks or when the installed package is imported and used. The project provides no lock file, hash verification, or trusted-index constraints to make dependency resolution reproducible.

Attack Path

  1. An attacker compromises a referenced package, one of its transitive dependencies, or the package distribution channel.
  2. The attacker publishes a malicious release that still satisfies the unconstrained dependency request.
  3. A user follows the documented pip install futu-api pandas command.
  4. The package manager resolves and installs the attacker-controlled release.
  5. Malicious code executes during package installation, import, or subsequent use of the trading client.

Impact Assessment

Dependency code generally executes with the privileges of the user running pip or the application. A successful supply-chain compromise could therefore access that user's files, environment variables, network resources, and application data.

Because the dependency is used to communicate with FutuOpenD, malicious dependency code could also attempt to observe sensitive account information, interfere with trading requests, or misuse an already unlocked trading session. The exact impact ...[truncated 113 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin every direct dependency to a reviewed version.
  • Generate and commit a lock file that also constrains transitive dependencies.
  • Require package hashes, for example through pip install --require-hashes -r requirements.txt.
  • Install packages only from an explicitly configured and trusted package index.
  • Add dependency vulnerability and integrity scanning to the release process.
  • Periodically update dependencies through a reviewed process rather than resolving unrestricted versions during deployment.
  • Prefer an isolated virtual environment and avoid installing the skill with administrator or root privileges.

T09 · Insecure Skill Coding Practices

Error
Location
client.py:155
Finding

Live Trading Environment Used by Default for Order Placement

Content
View full analysis

Vulnerability Details

File Location: client.py:155-163
Vulnerability Type: T09: Insecure Skill Coding Practices
Risk Level: High

Vulnerable Code

python
def place_order(
    self,
    price: float,
    qty: int,
    code: str,
    trd_side: TrdSide = TrdSide.BUY,
    order_type: OrderType = OrderType.NORMAL,
    trd_env: TrdEnv = TrdEnv.REAL
) -> Dict[str, Any]:

The default is subsequently passed directly to the trading API:

python
ret, data = ctx.place_order(
    price=price,
    qty=qty,
    code=code,
    trd_side=trd_side,
    order_type=order_type,
    trd_env=trd_env
)

Technical Analysis

place_order defaults to TrdEnv.REAL. A caller that omits trd_env therefore requests a live order rather than a simulated order. This is an unsafe default for an agent-accessible financial operation because an omitted optional parameter, ambiguous instruction, or automated calling error can produce a real financial transaction.

The method does not require a separate live-trading confirmation, impose transaction limits, or verify that the caller explicitly selected the real environment. Validation and authorization performed by FutuOpenD may still apply, but those controls do not eliminate the dangerous default once a real trading session has been unlocked.

Attack Path

  1. FutuOpenD is running and the relevant real trading account is available and unlocked.
  2. An agent, application, or user invokes place_order with a price, quantity, code, and side but omits trd_env.
  3. Python assigns TrdEnv.REAL to the omitted argument.
  4. The wrapper passes that value directly to ctx.place_order.
  5. FutuOpenD processes the request as a live order, subject to account permissions and market conditions.

A malicious caller with access to the wrapper could similarly rely on the default to make a real-trading request appear less explicit. The attack still req ...[truncated 694 chars]

Remediation
View remediation

Remediation Suggestions

  • Change the default to TrdEnv.SIMULATE.
  • For stronger protection, make trd_env mandatory so every caller must explicitly select an environment.
  • Require a separate explicit confirmation flag or confirmation callback before accepting TrdEnv.REAL.
  • Display and verify the security code, side, price, quantity, estimated value, and environment before submitting a live order.
  • Add configurable per-order and cumulative transaction limits.
  • Reject live orders unless a dedicated configuration option enables real trading.
  • Keep real trading disabled in development, testing, and agent evaluation environments.
  • Record tamper-resistant audit events for live-order requests and responses without logging trading passwords.
  • Add tests confirming that omitted parameters can never submit a real order.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The client can place real trades by default using TrdEnv.REAL, with no confirmation step, simulation-first behavior, or other safety interlock before a destructive financial action. In an agent setting, a prompt mistake, tool misuse, or malicious instruction could trigger irreversible market orders and direct financial loss.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The client exposes a trade-unlock method that accepts a plaintext password and forwards it directly to the trading API, but provides no warning about the sensitivity of this secret or guardrails around when it should be used. In an agent/skill context, this increases the chance that higher-level automation will request, log, store, or transmit trading credentials unsafely, enabling unauthorized account access if the password is exposed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill explicitly documents support for real trading via TrdEnv.REAL and order placement, but it does not present a clear warning that invoking these functions can place live market orders with immediate financial consequences. In an agent setting, this increases the risk of unintended or unauthorized trades because users may not appreciate that the documented examples can affect real funds.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The default group_name is set to "全部", and the implementation probes several Chinese locale-specific group names such as "港股", "美股", and "沪深". This imposes locale-specific behavior in the interface without explicit user opt-in or a documented language/locale selection mechanism.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The skill advertises access to positions, account balances, orders, deals, and watchlists without warning that these features expose sensitive financial and portfolio data. In an agent context, omission of a privacy notice can lead to over-collection, unintended disclosure, or unsafe sharing of brokerage information.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
75% confidence
Finding

The get_watchlist documentation hard-codes group-name examples in Chinese (全部, 港股, 美股, 沪深) without clarifying whether the skill is region-specific or offering an alternative locale. This can be a language/locale policy issue because the documentation implicitly assumes one language context without user opt-in or explanation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.