T09 · Insecure Skill Coding Practices
- Location
scripts/snaptrade_order.py:9- Finding
Direct Force-Order Execution Without Pre-Trade Validation or Confirmation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This SnapTrade skill is mostly coherent for portfolio reporting, but it also enables live brokerage trades and stores financial credentials without enough safety controls or upfront disclosure.
Install only if you intentionally want this skill to access brokerage data and you understand it contains live-trading capability. Before use, remove or disable the order scripts unless trading is required, require explicit confirmation and checked-order previews for any trade, protect the SnapTrade config file, and avoid forwarding financial reports through WhatsApp unless you accept that privacy exposure.
scripts/snaptrade_order.py:9Direct Force-Order Execution Without Pre-Trade Validation or Confirmation
scripts/snaptrade_common.py:24Credential File Is Written Before Restrictive Permissions Are Enforced
scripts/snaptrade_accounts.py:12Brokerage Account Numbers Are Exposed Through Standard Output
The skill description does not clearly disclose order-monitoring functionality tied to brokerage order execution. While monitoring is less severe than placing orders, hidden execution-related behavior can still mislead users and orchestration systems about the sensitivity of the skill's access and operational scope.
The skill description does not clearly disclose order-monitoring functionality tied to brokerage order execution. While monitoring is less severe than placing orders, hidden execution-related behavior can still mislead users and orchestration systems about the sensitivity of the skill's access and operational scope.
Within a skill presented as portfolio reporting/connectivity, the documented workflow includes direct buy/sell order placement. In financial contexts this materially increases risk because the capability can cause immediate asset movement and losses if invoked under assumptions appropriate only for reporting tasks.
The order-placement instructions default to market orders and do not prominently warn that these are real trades with immediate financial consequences. In a brokerage context, lack of an explicit risk warning and confirmation step can lead to accidental executions, slippage, and unintended losses.
This script places live buy/sell orders via client.trading.place_force_order, which materially exceeds the skill’s declared scope of brokerage connectivity, account registration, and portfolio reporting. A skill presented as read-oriented portfolio tooling but containing trade execution logic creates a dangerous capability mismatch that could enable unauthorized or unexpected transactions if invoked by an agent or user who reasonably assumes the skill is non-trading.
The skill documents shell execution, file reads/writes, and secret handling but does not declare any explicit tool scope or permissions boundary. In an agent setting, this weakens least-privilege controls and makes it easier for the skill to access sensitive files or execute commands beyond what is necessary for portfolio reporting.
The overview frames the skill as generating a daily total-value report, yet nearby instructions introduce real trade execution. This can cause dangerous trust confusion, especially for agents selecting skills by overview text, leading to use of a transaction-capable skill where a read-only reporting skill was expected.
The skill recommends automated daily WhatsApp reporting of portfolio value without warning that financial account data will be transmitted through a third-party messaging channel. This creates privacy and confidentiality risk, especially if messages are sent to the wrong recipient, stored insecurely, or exposed on a device.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
- Request signing is handled by the SDK via `request_after_hook` using `consumer_key`.
- The total is computed by summing each account’s `account.balance.total` from holdings; this avoids errors when accounts are added or removed.
- If multiple currencies are present, the script uses the first currency encountered.
- Keep secrets in the local config file with `chmod 600` permissions.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
This page is the landing reference for API endpoints. Use it to navigate to specific endpoint docs.
## Example: API Status
- GET https://api.snaptrade.com/api/v1/
- Checks API operational status + timestamp
If you need detailed endpoint schemas, use the official reference for the specific endpoint path.
The code writes configuration data to disk and sets restrictive permissions, which strongly suggests the file may contain sensitive credentials such as the consumer key referenced elsewhere in the file. There is no confirmation prompt, user-facing log/print, or explanatory comment/docstring warning that secrets will be persisted to a local file.
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
def save_config(data: Dict[str, Any], path: str = DEFAULT_CONFIG_PATH) -> None:
p = Path(path)
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(json.dumps(data, indent=2))
try:
os.chmod(p, 0o600)
except Exception:
The code stores the SnapTrade user secret directly into persistent configuration via cfg["user_secret"] followed by save_config(cfg). If that config is stored in plaintext or in a broadly accessible location, compromise of the file would expose a credential that can be reused to authenticate SnapTrade user operations, increasing the blast radius of local file disclosure or accidental config sharing.
The function reads client_id and consumer_key from configuration and uses them to initialize an API client, which is credential handling. The file contains no docstring, comment, or user-facing notice explaining that credentials are being loaded and used for API access.
No suspicious patterns detected.