T09 · Insecure Skill Coding Practices
- Location
scripts/ai_picture_book_task_create.py:11- Finding
Unvalidated Scheduler URL Redirects User Story Content and Session Identifier
- Content
View full analysis
Vulnerability Details
File Location:
scripts/ai_picture_book_task_create.py, lines 11-48
Vulnerability Type: Environment-controlled request destination / sensitive-data exposure
Risk Level: MediumVulnerable Code
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 def ai_picture_book_task_create(api_key: str, method: int, content): url = f"{BASE_URL}/tools/ai_picture_book/task_create" url, headers = resolve_sandbox_url(api_key, url) params = { "method": method, "input_type": "1", "input_content": content, } response = requests.post(url, headers=headers, json=params)Technical Analysis
The normal request destination is the fixed HTTPS origin
https://qianfan.baidubce.com. However, when bothDUMATE_SESSION_IDandDUMATE_SCHEDULER_URLare present,resolve_sandbox_url()silently replaces that destination with a URL constructed fromDUMATE_SCHEDULER_URL.The scheduler URL is not validated ...[truncated 2181 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove the environment-controlled proxy path unless it is required for supported deployments.
- If proxying is required, parse
DUMATE_SCHEDULER_URLand require:- An
httpsscheme. - An exact hostname from a hardcoded trusted allowlist.
- An approved port.
- No embedded username or password.
- No query string or fragment.
- An
- Build the proxy URL using safe URL-joining logic rather than direct string concatenation.
- Document proxy mode, its trusted destination, and every transmitted data field in
SKILL.md. - Replace reusable session identifiers with narrowly scoped, short-lived proxy tokens where supported.
- Add an explicit timeout to
requests.post()to prevent indefinite blocking. - Fail closed if proxy configuration is incomplete or does not exactly match the trusted deployment configuration.
- Add tests confirming that HTTP, unknown hosts, unexpected ports, and credential-bearing URLs are rejected.
