T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/ai_notes_task_create.py:36
- Finding
- Unvalidated Environment-Controlled Proxy Enables Sensitive Data Exfiltration## Vulnerability Details **File Location**: - `scripts/ai_notes_task_create.py:36-46, 63-96` - `scripts/ai_notes_task_query.py:14-41` - `scripts/ai_notes_poll.py:25-52` **Vulnerability Type**: Untrusted network destination and sensitive data disclosure **Risk Level**: High ### Vulnerable Code `scripts/ai_notes_task_create.py:36-46`: ```python url, headers = resolve_sandbox_url(api_key, "https://appbuilder.baidu.com/v2/tools/bos/upload") headers = { "Authorization": f"Bearer {api_key}", "X-Appbuilder-From": "openclaw", } with open(file_path, "rb") as f: files = {"file": (os.path.basename(file_path), f)} response = requests.post(url, headers=headers, files=files) response.raise_for_status() result = response.json() ``` `scripts/ai_notes_task_create.py:63-96`: ```python def resolve_sandbox_url(api_key: str, original_url: str) -> Tuple[str, Dict[str, str]]: """若当前在沙盒环境中,将目标 URL 替换为代理 URL,并返回需要附加的 headers。""" session_id = os.environ.get("DUMATE_SESSION_ID") scheduler_url = os.environ.get("DUMATE_SCHEDULER_URL") headers = { "Content-Type": "application/json", } if not session_id or not scheduler_url: if not api_key: raise ValueError("未设置 API Key,请通过环境变量 BAIDU_API_KEY 设置或使用") headers.update({ "Authorization": f"Bearer {api_key}", "X-Appbuilder-From": "openclaw", }) return original_url, headers parsed = urlparse(original_url) proxy_url = f"{scheduler_url}/api/qianfanproxy{parsed.path}" if parsed.query: proxy_url += f"?{parsed.query}" headers.update({ "Host": parsed.netloc, "X-Dumate-Session-Id": session_id, "X-Appbuilder-From": "desktop", }) return proxy_url, headers ``` `scripts/ai_notes_task_query.py:14-41`: ```python def resolve_sandbox_url(api_key: str, original_url: str) -> Tuple[str, Dict ...[truncated 4957 chars]
- Remediation
- ## Remediation Suggestions 1. Enforce an exact allowlist of trusted scheduler hostnames rather than accepting an arbitrary URL: - Require the `https` scheme. - Reject embedded credentials, fragments, unexpected ports, IP literals, and noncanonical hostnames. - Compare the parsed hostname against explicitly configured platform domains. 2. Obtain the scheduler endpoint from a trusted runtime configuration channel where possible. Do not treat ordinary inheritable environment variables as sufficient proof that a destination is trusted. 3. Validate the final resolved URL immediately before every request, including after any redirect. Disable redirects or verify every redirect target for requests carrying files, API keys, session identifiers, or task data. 4. Avoid overwriting the validated headers returned by `resolve_sandbox_url()`. Build upload headers through one centralized function so direct and proxy modes have explicit, independently reviewed credential policies. 5. Never transmit `BAIDU_API_KEY` to a sandbox proxy unless that proxy is explicitly designed and authorized to receive it. Prefer proxy-scoped, short-lived credentials where proxy authentication is required. 6. Add an explicit timeout to the upload request: ```python response = requests.post( url, headers=headers, files=files, timeout=(10, 120), allow_redirects=False, ) ``` 7. Before uploading a local file, clearly disclose the validated destination to the user and obtain confirmation when the destination differs from the documented Baidu service. 8. Apply the same centralized destination validation to task creation, manual query, and automatic polling to prevent task IDs, video URLs, and session metadata from being redirected.
