T09 · Insecure Skill Coding Practices
- Location
scripts/portfolio.py:64- Finding
API Credential Can Be Redirected to an Arbitrary Endpoint
- Content
View full analysis
OpenAI: api_key = os.environ.get("AISA_API_KEY") if not api_key: print("❌ Error: AISA_API_KEY environment variable is not set.", file=sys.stderr) sys.exit(1) base_url = os.environ.get("AISA_BASE_URL", "https://api.aisa.one/v1") return OpenAI(api_key=api_key, base_url=base_url) ``` ### Technical Analysis The script reads the sensitive `AISA_API_KEY` credential and supplies it to an OpenAI-compatible client. The destination URL can be overridden through `AISA_BASE_URL` without validating its scheme, hostname, or trust relationship. When `fetch_prices()` invokes `client.chat.completions.create()`, the client sends an authenticated request to the configured base URL. Consequently, a modified process environment can redirect requests carrying the legitimate AISA credential to an arbitrary server. The code also does not require HTTPS, so a configuration using plaintext HTTP could expose the credential and request contents in transit. The default URL, `https://api.aisa.one/v1`, is consistent with the Skill's declared live-pricing functionality. The risk arises from allowing the same credential to be attached to an unrestricted alternative host, which exceeds the minimum network privileges required by the declared behavior. ### Attack Path 1. An attacker, compromised launcher, wrapper script, or unsafe runtime configuration sets `AISA_BASE_URL` to an attacker-controlled endpoint. 2. The user invokes `python3 scripts/portfolio.py show`. 3. `get_client()` reads the legitimate `AISA_API_KEY` and constructs a client using the malicious base URL. 4. `fetch_prices()` calls the chat-completions endpoint. 5. The client sends an authenticated request to the attacker-controlled server. 6. The server captures the API credent ...[truncated 722 chars]- Remediation
View remediation
