T03 · Remote Payload Retrieval and Execution
- Location
README.md:21- Finding
Unpinned Remote Installer Is Piped Directly into a Privileged Shell
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a disclosed IBKR trading skill, but it needs Review because live-order execution relies on agent-readable local tokens and mutable setup components that handle broker credentials.
Install only if you are comfortable reviewing a trading-capable skill. Use paper mode first, pin and verify the Docker gateway and Python dependencies before supplying IBKR credentials, keep symbol and notional caps tight, avoid broad scheduled execution, and treat any live-mode use as capable of placing real broker orders.
README.md:21Unpinned Remote Installer Is Piped Directly into a Privileged Shell
requirements.txt:1Unpinned Third-Party Gateway and Python Dependencies Create Supply-Chain Exposure
scripts/ibkr_execute_trade.py:54Human Confirmation Is an Instructional Convention Rather Than an Enforced Authorization Boundary
scripts/_pending.py:45Unsanitized Proposal IDs Permit Path Traversal Outside the Pending Directory
scripts/_guardrails.py:50Daily Notional Cap Check and Accounting Are Non-Atomic
scripts/ibkr_propose_trade.py:27Market Orders Can Exceed Notional Caps Because Checks Use a Stale Reference Price
scripts/_audit.py:21Sensitive Portfolio and Trade Records Are Written Without Enforced Restrictive Permissions
scripts/ibkr_gateway_status.py:39Routine Diagnostic and Balance Commands Disclose Full Broker Account Identifiers
The | sh construct is the dangerous sink that turns remote content into immediate shell execution, enabling command injection through any compromise of the fetched script or transport path. In this skill's context, host compromise could expose IBKR credentials, .env secrets, and trading infrastructure, amplifying the impact beyond a generic workstation setup issue.
curl -fsSL https://get.docker.com | sh
docker --version
The description claims a full IBKR investing skill with human-in-the-loop trade confirmation and support for balances, quotes, trading, DCA, and portfolio snapshots. This code chunk instead only tests TCP connectivity and IB API handshake status for the gateway, printing troubleshooting guidance. While this could be a supporting utility within such a skill, the actual behavior of the provided code chunk does not match the declared purpose as stated. There is no trade logic, no confirmation gate logic, and none of the user-facing investing functions described.
The declared description presents a broad IBKR investing/trading skill centered on balances, quotes, portfolio actions, DCA, and especially trade execution with a strict confirmation gate. The supplied code chunk instead has a narrower and materially different purpose: retrieving historical price bars and optionally calculating SMA/RSI overlays. While market-data lookup is adjacent to 'look up quotes,' historical candles with indicators and generated trading signals are a distinct capability not stated in the description. More importantly, the code does not implement any of the signature declared behaviors like human-in-the-loop trade confirmation, trading mode controls, order placement, balance retrieval, or portfolio snapshots. This is a meaningful description-to-behavior mismatch for the provided chunk.
The description presents a broad IBKR trading skill with human-in-the-loop confirmation and explicit safeguards around live trading. The supplied code, however, only implements the daily snapshot/reporting portion: it reads account/position data, fetches delayed quotes and historical closes, computes changes, writes a local JSON snapshot, and prints a summary. There is no order placement, no confirmation gate, no DCA logic, and no explicit handling of paper/live mode selection in this file. While the snapshot behavior is mentioned in the declared description, the declared purpose substantially overstates the code chunk’s capabilities, and the code also performs local file persistence that is not disclosed in the description. Therefore the description does not accurately represent what this specific code chunk actually does.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
mkdir -p ~/.aeon/ibkr-runtime && cd ~/.aeon/ibkr-runtime
git clone https://github.com/gnzsnz/ib-gateway-docker.git
cd ib-gateway-docker
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
export IBKR_MAX_DAILY_NOTIONAL_USD=1000
`chmod 600 ~/.aeon/.env`. Then either restart aeon or `source ~/.aeon/.env` if running interactively.
## Going live
Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.
dca_dip_state.json # drawdown-trigger state
Files are 0600 so the confirmation token is not world-readable. Pending proposals expire automatically after 10 minutes.
## What the user types in chat
The skill explicitly instructs use of powerful capabilities including shell, file_read, file_write, and environment-dependent behavior, but it declares no tool scope or permission boundary. In a trading skill, missing least-privilege constraints increases the blast radius of prompt injection, misrouting, or operator error, because the agent can read local files, persist state, and invoke execution-oriented scripts without an explicit allowlist.
The activation criteria are broad enough to match generic finance-related requests such as balances, quotes, investing, DCA, and portfolio snapshots. In a skill with shell and file capabilities and potential trade execution, over-broad triggering raises the chance of accidental invocation, context confusion, or prompt-injection-assisted routing into a higher-risk toolchain than the user intended.
The skill first requires using the printed absolute pending-file path verbatim, then later tells the operator to read a guessed fixed path under ~/.aeon/ibkr/pending/.json. This inconsistency can cause the agent to read the wrong file, fail open on multi-user systems, or use stale/cross-session confirmation data, weakening the trade confirmation control in a sensitive trading workflow.
The skill directs persistent storage of strategy state, snapshots, and audit data in the user's home directory across sessions. Persistence is not automatically unsafe, but in a financial context it creates privacy and integrity risk: stored portfolio history, trigger state, and audit trails may be exposed to other tools, reused out of context, or tampered with to influence future trading recommendations.
1. Decide what observations the strategy needs. Read from `ibkr_snapshot.py` (current state), `~/.aeon/ibkr/snapshots/*.json` (history), `~/.aeon/ibkr/audit.jsonl` (lifecycle events), and `ibkr_get_candles.py --indicators` (signal).
2. Define the trigger condition. Either a scheduled task that runs daily and checks the condition, or a passive observation surfaced in the snapshot.
3. The trigger NEVER places a trade itself — it produces a recommendation that the agent (or scheduled task) can pass to `ibkr_propose_trade.py`. User still YES-confirms each fill.
4. Write any required state to `~/.aeon/ibkr/<strategy_name>_state.json` (mode 600).
5. Append `audit.jsonl` events for transparency.
The `ibkr_dca_dip.py` script is the canonical example of this shape. Follow it for new strategies.
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
#!/usr/bin/env python3
"""Discard a pending IBKR proposal (the 'NO <id>' path).
No confirmation token required — cancelling a proposal before any IBKR order
has been placed is always safe.
"""
from __future__ import annotations
This script prints sensitive financial data including account identifiers, net liquidation value, cash, positions value, buying power, and P&L directly to stdout with no masking, consent prompt, or output-scope control. In an agent setting, stdout may be surfaced to chat logs, stored in run history, or exposed to other tooling, creating a real confidentiality risk even though the script is read-only.
The script emits directional trading guidance such as 'consider buy' and 'consider sell' based solely on RSI thresholds, without any user-facing disclaimer or context about the signal's limitations. In an investing skill that can be used to inform or initiate trades, this increases the risk that users or downstream agents treat a simplistic indicator as actionable advice, leading to poor investment decisions.
Piping a remote script from get.docker.com directly into sh executes code fetched over the network without prior verification or review. If the remote content, TLS trust chain, or delivery path is compromised, the user could run arbitrary code on the host, which is especially risky in a trading skill environment that also manages credentials and can place orders.
curl -fsSL https://get.docker.com | sh
docker --version
The dependency specification uses a lower-bound only (ib_async>=1.0.1), which permits installation of any future release, including unreviewed or breaking versions. In a trading-related skill, supply-chain compromise or an unexpected behavioral change in the brokerage client library could affect market data access or trade execution paths.
ib_async>=1.0.1
pandas>=2.0
numpy>=1.24
pandas>=2.0 is unpinned, so builds are not reproducible and may pull in future releases with undiscovered vulnerabilities or incompatible behavior. Although pandas is not typically a direct remote-execution vector in normal use, unreviewed upgrades in a financial workflow can still introduce reliability or security issues around data handling.
ib_async>=1.0.1
pandas>=2.0
numpy>=1.24
Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.
numpy>=1.24 allows arbitrary newer versions to be installed, weakening reproducibility and increasing exposure to supply-chain or compatibility issues. In this investing skill, incorrect numerical behavior or a compromised package could affect calculations used for portfolio analysis or trade sizing.
ib_async>=1.0.1
pandas>=2.0
numpy>=1.24
Because numpy is unpinned, dependency resolution could select a version with known security issues depending on environment, mirrors, or transitive constraints. While the manifest's minimum version excludes some older CVEs, the lack of a fixed resolved version leaves security posture unverifiable and is undesirable in a finance-related skill where numerical integrity matters.