Back to skill

Security audit

Alpaca Markets CLI

Security checks for vulnerabilities and agentic risk

Overview

This Alpaca trading skill is coherent, but it needs review because it can use brokerage credentials for live account-changing actions and does not sufficiently restrict where those credentials are sent.

Review this before installing. Use paper-trading credentials first, avoid setting ALPACA_BASE_URL except to an official Alpaca URL you have verified, and do not give the skill live trading keys unless you are comfortable with an agent being able to place orders, cancel orders, and close positions. Treat bulk cancel and close-all-position calls as requiring explicit human confirmation.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/alpaca_api.py:52
Finding
Arbitrary Base URL Allows Alpaca Credential Exfiltration## Vulnerability Details **File Location**: `scripts/alpaca_api.py`, lines 52-84 **Vulnerability Type**: Unrestricted credential destination and insufficient URL validation **Risk Level**: High ### Vulnerable Code ```python base_url = os.getenv("ALPACA_BASE_URL", "https://paper-api.alpaca.markets") api_key = os.getenv("ALPACA_API_KEY") api_secret = os.getenv("ALPACA_API_SECRET") if not api_key or not api_secret: print("Error: Set ALPACA_API_KEY and ALPACA_API_SECRET environment variables", file=sys.stderr) sys.exit(1) if not endpoint.startswith("/"): print("Error: endpoint must start with '/' (example: /v2/account)", file=sys.stderr) sys.exit(2) url = f"{base_url}{endpoint}" headers = { "APCA-API-KEY-ID": api_key, "APCA-API-SECRET-KEY": api_secret, "Content-Type": "application/json", } allowed_methods = {"GET", "POST", "PUT", "PATCH", "DELETE"} method = method.upper() if method not in allowed_methods: print(f"Unsupported method: {method}. Supported: {', '.join(sorted(allowed_methods))}", file=sys.stderr) sys.exit(2) try: response = requests.request( method=method, url=url, headers=headers, params=params, json=data, timeout=timeout, ) ``` ### Technical Analysis `ALPACA_BASE_URL` is accepted without validating its scheme, hostname, port, path, user-information component, query, or fragment. The only related check verifies that the endpoint begins with `/`, which does not constrain the destination host. The helper then attaches both sensitive Alpaca authentication headers to the resulting URL. Consequently, anyone able to influence the process environment can redirect credentials to an arbitrary server. Plain HTTP destinations are also accepted, allowing credentials to be exposed through network interception. The `requests` library follows redirects by default. Because these credentials ...[truncated 2042 chars]
Remediation
## Remediation Suggestions 1. Replace the arbitrary base URL with an explicit environment selector such as `ALPACA_ENVIRONMENT=paper|live`. 2. Map that selector internally to exact trusted origins: - `https://paper-api.alpaca.markets` - `https://api.alpaca.markets` - `https://data.alpaca.markets` only for operations that require the market-data API. 3. If custom base URLs are operationally necessary, parse them with `urllib.parse.urlsplit()` and require: - The `https` scheme. - A hostname from an explicit allowlist. - No username or password component. - No unexpected port. - No query or fragment. - An empty or explicitly permitted base path. 4. Set `allow_redirects=False` for authenticated requests. If redirects must be supported, validate each destination against the same trusted-origin allowlist before retransmitting credentials. 5. Use separate request clients or credential scopes for trading and market-data services so credentials are sent only where required. 6. Fail closed with a clear error when the configured destination is not trusted. 7. Add automated tests covering attacker-controlled hosts, plain HTTP URLs, user-information URLs, unexpected ports, malformed URLs, and redirects to untrusted origins. 8. Continue defaulting to paper trading, but do not treat documentation warnings as a substitute for runtime destination enforcement.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description says this skill provides programmatic integration with Alpaca Markets brokerage services. However, the supplied code chunk is not brokerage logic at all; it is a developer utility script for validating package metadata and documentation consistency. Its actions are limited to reading local files, parsing JSON/frontmatter/YAML-like text, analyzing Python AST for getenv calls, and verifying declared environment variables and manifest fields. This is a materially different primary purpose from stock/options/crypto trading integration, so this is a clear description-behavior mismatch.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- **List Orders**: `GET /v2/orders`
- **Get Order**: `GET /v2/orders/{order_id}`
- **Replace Order**: `PATCH /v2/orders/{order_id}`
- **Cancel Order**: `DELETE /v2/orders/{order_id}`
- **Cancel All Orders**: `DELETE /v2/orders`
- **Get Positions**: `GET /v2/positions`
- **Close Position**: `DELETE /v2/positions/{symbol}`
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- **Get Order**: `GET /v2/orders/{order_id}`
- **Replace Order**: `PATCH /v2/orders/{order_id}`
- **Cancel Order**: `DELETE /v2/orders/{order_id}`
- **Cancel All Orders**: `DELETE /v2/orders`
- **Get Positions**: `GET /v2/positions`
- **Close Position**: `DELETE /v2/positions/{symbol}`
- **Close All Positions**: `DELETE /v2/positions`
Confidence
80% confidence
Finding
The skill explicitly exposes a bulk-destructive operation to cancel all orders, and the documentation does not pair it with strong confirmation or live-account safeguards. In a brokerage skill, mass cancellation can disrupt trading strategies or risk controls and is especially dangerous if an agent misinterprets user intent or is pointed at live credentials.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- **Cancel Order**: `DELETE /v2/orders/{order_id}`
- **Cancel All Orders**: `DELETE /v2/orders`
- **Get Positions**: `GET /v2/positions`
- **Close Position**: `DELETE /v2/positions/{symbol}`
- **Close All Positions**: `DELETE /v2/positions`
- **Get Assets**: `GET /v2/assets`
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- **Cancel All Orders**: `DELETE /v2/orders`
- **Get Positions**: `GET /v2/positions`
- **Close Position**: `DELETE /v2/positions/{symbol}`
- **Close All Positions**: `DELETE /v2/positions`
- **Get Assets**: `GET /v2/assets`

### Market Data
Confidence
82% confidence
Finding
The documented 'close all positions' operation is an inherently high-risk bulk liquidation action, and the skill text does not provide strong warnings or execution safeguards. In context, this skill manages brokerage accounts and can affect real assets, so exposing account-wide liquidation without explicit caution makes accidental or unauthorized loss more plausible.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- Crypto example: {"symbol": "BTC/USD", "notional": "100", "side": "buy", "type": "market", "time_in_force": "gtc"}
- GET /v2/orders/{order_id} - Get specific order
- PATCH /v2/orders/{order_id} - Replace an order (qty, time_in_force, limit_price, stop_price, trail)
- DELETE /v2/orders/{order_id} - Cancel order
- DELETE /v2/orders - Cancel all open orders

### Positions
Confidence
87% confidence
Finding
The documented endpoint allows cancellation of a specific order, which is a sensitive state-changing operation with financial consequences if triggered by untrusted or manipulated input. In an agent-integrated trading skill, exposing this operation without emphasizing authorization checks, confirmation, and order/account validation can enable unintended trade disruption or sabotage.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- GET /v2/orders/{order_id} - Get specific order
- PATCH /v2/orders/{order_id} - Replace an order (qty, time_in_force, limit_price, stop_price, trail)
- DELETE /v2/orders/{order_id} - Cancel order
- DELETE /v2/orders - Cancel all open orders

### Positions
- GET /v2/positions - List all positions
Confidence
96% confidence
Finding
The cancel-all-open-orders endpoint is especially dangerous because a single invocation can alter an entire trading strategy and disrupt multiple pending executions at once. In this skill context, the lack of warnings or prescribed safeguards makes tool abuse more dangerous, particularly if an LLM agent misinterprets instructions or is prompt-injected into issuing broad cancellation commands.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Positions
- GET /v2/positions - List all positions
- GET /v2/positions/{symbol} - Get position for symbol
- DELETE /v2/positions/{symbol} - Close position
- DELETE /v2/positions - Close all positions

### Assets
Confidence
90% confidence
Finding
Closing a position is a destructive financial action that can realize gains or losses immediately and may have tax or risk-management consequences. Within a brokerage automation skill, documenting this action without warning about confirmation, symbol validation, and live-vs-paper environment separation creates a meaningful risk of accidental or induced liquidation.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- GET /v2/positions - List all positions
- GET /v2/positions/{symbol} - Get position for symbol
- DELETE /v2/positions/{symbol} - Close position
- DELETE /v2/positions - Close all positions

### Assets
- GET /v2/assets - List assets (params: status=active)
Confidence
98% confidence
Finding
The close-all-positions endpoint can liquidate an entire portfolio in one call, making it the highest-risk operation in this reference. In the context of an AI-accessible trading skill, this is especially dangerous because prompt injection, misunderstanding, or parameter abuse could trigger catastrophic portfolio-wide losses or unwanted liquidation without any documented safeguards.

Credential Access

High
Category
Privilege Escalation
Content
)

    if credential.get("env_vars") != EXPECTED_REQUIRED_ENV_VARS:
        fail("primary_credential.env_vars must match required_env_vars")

    if not credential.get("type"):
        fail("primary_credential.type is required")
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill declares access to sensitive environment variables and describes network-capable helper scripts, but the manifest shown in SKILL.md does not define an explicit tool scope such as permissions or allowed-tools. In an agent ecosystem, missing scope boundaries can let a trading-capable skill access network, files, and credentials more broadly than users expect, increasing the chance of unintended API calls or secret exposure.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill documents destructive brokerage actions such as placing orders, canceling orders, and closing positions, but it does not provide a clear, prominent warning about financial loss, irreversible market actions, or the danger of accidentally using live credentials. In a trading context, weak risk signaling can contribute to harmful real-account operations by users or downstream agents.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This reference documents high-risk, destructive brokerage operations such as canceling all open orders and closing all positions without any cautionary language, confirmation guidance, or mention of account-environment safeguards. In a trading skill, that omission increases the chance that an agent or user will invoke irreversible financial actions in the wrong context, especially against a live account.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
Confidence
93% confidence
Finding
The dependency is specified as `requests>=2.31.0`, which allows any future release to be installed and makes builds non-reproducible. This creates supply-chain risk because a later vulnerable or breaking version could be pulled in without review, which is more concerning in a trading skill that may handle credentials and execute brokerage actions.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
88% confidence
Finding
Because `requests` is unpinned, it is not possible to verify that the installed version is free from known advisories, including issues that may affect credential handling or TLS/request behavior. In the context of an Alpaca trading integration, this is more dangerous than a generic utility because compromised HTTP behavior could expose API keys, account data, or trade requests.

Static analysis

No suspicious patterns detected.