T09 · Insecure Skill Coding Practices
Error
- Location
- aifei_api.py:115
- Finding
- OA bearer token disclosure through unrestricted absolute URLs<![CDATA[ ## Vulnerability Details **File Location**: `aifei_api.py:115-127`; `aifei.py:145-161` **Vulnerability Type**: Authenticated server-side request redirection and credential disclosure **Risk Level**: High ### Vulnerable Code ```python def _url(self, path, use_biz_prefix=False): if path.startswith('http'): return path if path.startswith('/dev-api') or path.startswith('/prod-api'): return f'{self.base_url}{path}' prefix = self.config.get('api_prefix_biz', self.config['api_prefix']) if use_biz_prefix else self.config['api_prefix'] return f'{self.base_url}{prefix}/{path.lstrip("/")}' def _headers(self): h = {'Content-Type': 'application/json;charset=UTF-8'} if self.token: h['Authorization'] = f'Bearer {self.token}' return h ``` ```python def cmd_raw(client, args): method = args.method.upper() path = args.path data = json.loads(args.data) if args.data else None if method == 'GET': result = client.get(path, biz=args.biz) elif method == 'POST': result = client.post(path, data, biz=args.biz) elif method == 'PUT': result = client.put(path, data, biz=args.biz) else: print(f'Unsupported method: {method}') return print(json.dumps(result, ensure_ascii=False, indent=2)[:2000]) ``` ### Technical Analysis The raw API command accepts a caller-supplied path, while `_url()` explicitly permits values beginning with `http`. The request methods subsequently attach the current OA bearer token through `_headers()` regardless of the destination. Consequently, an absolute URL can redirect an authenticated request away from the intended OA servers. This behavior is unnecessary for the declared OA client functionality because legitimate operations only require requests to the two configured OA origins. The check also accepts both HTTP and HTTPS URLs without parsing or validating the destination hostname, port, scheme, or resolved address. ### Attac ...[truncated 980 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove support for absolute URLs from `_url()`. 2. Accept only relative OA API paths. 3. Parse the final URL with `urllib.parse.urlparse()` and require an exact allowlisted tuple of scheme, hostname, and port. 4. Require HTTPS for every authenticated request. 5. Attach authentication headers only after confirming that the destination is an approved OA origin. 6. Disable redirects or validate every redirect target before forwarding credentials. 7. Restrict or remove the raw API command from normal Skill operation. 8. Add tests proving that external URLs, scheme-relative URLs, encoded hostnames, and unapproved ports are rejected. ]]>
