T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/swarm_runner.py:98
- Finding
- Arbitrary Environment Secret Disclosure Through a Configurable API Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/swarm_runner.py`, lines 98 and 106-136 **Vulnerability Type**: Credential disclosure and server-side request forgery through untrusted configuration **Risk Level**: High ### Vulnerable Code ```python api_key = os.environ.get( api_config.get('api_key_env', 'GROQ_API_KEY'), api_config.get('api_key', '') ) base_urls = { 'groq': 'https://api.groq.com/openai/v1/chat/completions', 'openai': 'https://api.openai.com/v1/chat/completions', 'ollama': 'http://localhost:11434/v1/chat/completions', } url = api_config.get('base_url') or base_urls.get( provider, base_urls['groq'] ) headers = {'Content-Type': 'application/json'} if api_key: headers['Authorization'] = f'Bearer {api_key}' payload = { 'model': model, 'messages': [ {'role': 'system', 'content': system_prompt}, {'role': 'user', 'content': user_msg} ], 'max_tokens': max_tokens, 'temperature': agent['temperature'] } try: if HAS_REQUESTS: r = requests.post( url, json=payload, headers=headers, timeout=30 ) ``` ### Technical Analysis The configuration independently controls both `api_key_env` and `base_url`. The program retrieves the value of the named environment variable and places it in the HTTP `Authorization` header without verifying that the destination is authorized to receive that credential. There is no: - Allowlist of approved API hosts. - Binding between a provider, its official endpoint, and its expected credential variable. - Restriction against private, loopback, link-local, or cloud metadata destinations. - HTTPS requirement for custom remote endpoints. - User confirmation before transmitting a credential to an overridden endpoint. - Restriction on which environment-variable names may be selected. Consequently, anyone able to supply or modify the configuration can select an environment variable availabl ...[truncated 2035 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Define an explicit endpoint allowlist for every supported provider: ```python PROVIDERS = { "groq": { "url": "https://api.groq.com/openai/v1/chat/completions", "key_env": "GROQ_API_KEY", }, "openai": { "url": "https://api.openai.com/v1/chat/completions", "key_env": "OPENAI_API_KEY", }, } ``` 2. Bind each provider to its expected credential-variable name rather than accepting an arbitrary environment-variable name from configuration. 3. Disable `base_url` overrides by default. If custom endpoints are necessary: - Require an explicit command-line opt-in. - Display the destination hostname before execution. - Require confirmation before attaching credentials. - Maintain a separate credential specifically authorized for that endpoint. 4. Require HTTPS for all non-loopback endpoints. Permit plaintext HTTP only for a verified loopback Ollama address. 5. Resolve the destination hostname and reject loopback, private, link-local, multicast, reserved, and cloud metadata addresses unless an explicit local-provider mode requires them. 6. Revalidate the resolved address after redirects or disable redirects entirely to prevent redirect-based allowlist bypasses. 7. Never forward a provider credential to a host that does not match the provider's approved hostname. 8. Document that configuration files are security-sensitive and must not be accepted from untrusted sources without review. ]]>
