T09 · Insecure Skill Coding Practices
- Location
scripts/analyze_stock.py:118- Finding
API Credential Exposure Through an Unrestricted Base URL Override
- Content
View full analysis
Vulnerability Details
File Location:
scripts/analyze_stock.py, lines 118–124 and 159–166
Vulnerability Type: Unrestricted network destination for authenticated API requests
Risk Level: HighVulnerable Code
python def get_client() -> 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) print(" Set it with: export AISA_API_KEY=your_key_here", 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)The resulting client is subsequently used for an authenticated request:
python try: response = client.chat.completions.create( model=model, messages=[ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": prompt}, ], temperature=0.1, )Technical Analysis
The Skill legitimately needs to send the requested ticker symbols and analysis prompt to the declared AISA API. Sending
AISA_API_KEYto the defaulthttps://api.aisa.one/v1service is therefore consistent with its documented functionality.However, the destination is controlled by the undeclared
AISA_BASE_URLenvironment variable without scheme or hostname validation. The OpenAI client usesAISA_API_KEYto authenticate requests sent through this configured base URL. If the variable points to an attacker-controlled API-compatible endpoint, the client can disclose the API credential and request contents to that endpoint.This behavior exceeds the minimum privileges required by the declared functionality because the Skill only documents use of the AISA service and does not require unrestricted authenticated communication with arbitrary hosts. The code does not explicitly place the key in the model prompt o ...[truncated 1651 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove the
AISA_BASE_URLoverride if custom endpoints are not an intended and documented feature:python return OpenAI( api_key=api_key, base_url="https://api.aisa.one/v1", ) -
If endpoint customization is required, declare it in
SKILL.mdand validate it before constructing the client:- Require the
httpsscheme. - Maintain an explicit allowlist of trusted hostnames.
- Reject embedded user information and credentials.
- Reject unexpected ports, IP literals, and malformed URLs.
- Ensure redirects cannot transfer authenticated requests to an untrusted host.
- Require the
-
Use separate, narrowly scoped credentials for custom endpoints rather than forwarding the AISA production credential.
-
Apply server-side restrictions to the key where supported, including quota limits, endpoint restrictions, expiration, and key rotation.
-
Clearly disclose that ticker symbols and prompts are sent to an external service, while ensuring that unrelated environment variables, files, and local credentials are never included.
-
