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

Content
View full analysis

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
View 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.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · SKILL.md (reported line 61)May include surrounding context.

md
- **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}`

Tool Parameter Abuse

High
Category
Tool Misuse
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.

Content

Scanner excerpt · SKILL.md (reported line 62)May include surrounding context.

md
- **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`

Tool Parameter Abuse

High
Category
Tool Misuse
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).

Content

Scanner excerpt · SKILL.md (reported line 64)May include surrounding context.

md
- **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`

Tool Parameter Abuse

High
Category
Tool Misuse
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.

Content

Scanner excerpt · SKILL.md (reported line 65)May include surrounding context.

md
- **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

Tool Parameter Abuse

High
Category
Tool Misuse
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.

Content

Scanner excerpt · references/api_reference.md (reported line 31)May include surrounding context.

md
- 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

Tool Parameter Abuse

High
Category
Tool Misuse
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.

Content

Scanner excerpt · references/api_reference.md (reported line 32)May include surrounding context.

md
- 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

Tool Parameter Abuse

High
Category
Tool Misuse
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.

Content

Scanner excerpt · references/api_reference.md (reported line 37)May include surrounding context.

md
### 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

Tool Parameter Abuse

High
Category
Tool Misuse
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.

Content

Scanner excerpt · references/api_reference.md (reported line 38)May include surrounding context.

md
- 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)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/validate_registry_metadata.py (reported line 218)May include surrounding context.

python
)

    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")

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
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.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.31.0

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.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.