T09 · Insecure Skill Coding Practices
- 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: HighVulnerable 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_URLis 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
requestslibrary follows redirects by default. Because these credentials ...[truncated 2042 chars]- Remediation
View remediation
Remediation Suggestions
- Replace the arbitrary base URL with an explicit environment selector such as
ALPACA_ENVIRONMENT=paper|live. - Map that selector internally to exact trusted origins:
https://paper-api.alpaca.marketshttps://api.alpaca.marketshttps://data.alpaca.marketsonly for operations that require the market-data API.
- If custom base URLs are operationally necessary, parse them with
urllib.parse.urlsplit()and require:- The
httpsscheme. - 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.
- The
- Set
allow_redirects=Falsefor authenticated requests. If redirects must be supported, validate each destination against the same trusted-origin allowlist before retransmitting credentials. - Use separate request clients or credential scopes for trading and market-data services so credentials are sent only where required.
- Fail closed with a clear error when the configured destination is not trusted.
- Add automated tests covering attacker-controlled hosts, plain HTTP URLs, user-information URLs, unexpected ports, malformed URLs, and redirects to untrusted origins.
- Continue defaulting to paper trading, but do not treat documentation warnings as a substitute for runtime destination enforcement.
- Replace the arbitrary base URL with an explicit environment selector such as
