T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/http_proxy.py:166
- Finding
- Unauthenticated HTTP Proxy Exposes Credential-Backed AI Provider Access<![CDATA[ ## Vulnerability Details **File Location**: `scripts/http_proxy.py:166-213`, `scripts/http_proxy.py:237-248`, `scripts/failover_proxy.py:156-186` **Vulnerability Type**: Missing authentication and access control **Risk Level**: High when bound to a network-accessible interface; Low with the default loopback-only binding ### Vulnerable Code ```python def do_GET(self): parsed = urlparse(self.path) if parsed.path == '/health': config, state = self.app.load() return self._json(200, { 'ok': True, 'profiles': list(config.get('task_profiles', {}).keys()), 'providers': list(config.get('providers', {}).keys()), 'state_file': self.app.state_file, 'state': state, }) return self._json(404, {'error': 'NOT_FOUND'}) def do_POST(self): parsed = urlparse(self.path) if parsed.path not in ('/v1/chat/completions', '/chat/completions'): return self._json(404, {'error': 'NOT_FOUND'}) length = int(self.headers.get('Content-Length', '0')) raw = self.rfile.read(length) try: payload = json.loads(raw.decode('utf-8')) if raw else {} except Exception: return self._json(400, {'error': 'INVALID_JSON'}) profile, profile_source, profile_reason = resolve_profile( self.headers, payload, fallback=self.app.default_profile ) try: config, state = self.app.load() result = call_with_failover(config, state, profile, payload) self.app.save(state) except KeyError as e: return self._json(400, { 'error': 'UNKNOWN_PROFILE_OR_PROVIDER', 'detail': str(e) }) except Exception as e: return self._json(500, { 'error': 'PROXY_ERROR', 'detail': str(e) }) ``` ```python ap.add_argument('--config', required=True) ap.add_argument('--state-file', default='/tmp/api-failover-state.json') ap.add_argument('--profile', default='default') ap ...[truncated 4270 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require authentication for all nontrivial endpoints: - Accept a dedicated proxy bearer token. - Compare tokens using `hmac.compare_digest`. - Prefer mTLS for shared or production environments. - Do not reuse upstream provider credentials as proxy-client credentials. 2. Enforce safe binding: - Refuse non-loopback `--host` values unless authentication is explicitly configured. - Emit a prominent warning before listening on a non-loopback interface. - Document firewall and network-segmentation requirements. 3. Add authorization controls: - Restrict which clients may select `critical` or other expensive profiles. - Consider ignoring client-selected routing hints unless explicitly enabled. - Apply per-client provider, model, token, and cost limits. 4. Add abuse controls: - Enforce a maximum `Content-Length` before reading the request body. - Add rate limiting, concurrency limits, and request timeouts. - Enforce maximum token and message-size limits. 5. Minimize health output: - Return only a basic readiness result to unauthenticated callers. - Protect detailed provider and circuit-breaker diagnostics with administrative authentication. - Do not disclose local state-file paths over the network. ]]>
