T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/qwen-image-gen.js:691
- Finding
- DashScope API credentials can be forwarded to an arbitrary configured endpoint<![CDATA[ ## Vulnerability Details **File Location**: `scripts/qwen-image-gen.js:691-692`, with credential-bearing network sinks at `scripts/qwen-image-gen.js:508-514`, `526-531`, and `535-541` **Vulnerability Type**: Unvalidated authenticated endpoint configuration **Risk Level**: High ### Vulnerable Code ```js const apiKey = firstNonEmpty(process.env.DASHSCOPE_API_KEY, config.apiKey); const baseUrl = String(firstNonEmpty(process.env.DASHSCOPE_BASE_URL, config.baseUrl, DEFAULT_BASE_URL)).replace(/\/$/, ''); ``` The API key is subsequently attached to requests sent to the selected base URL: ```js async function createTask(baseUrl, apiKey, request) { const result = await requestJson(`${baseUrl}${request.endpoint}`, { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json', 'X-DashScope-Async': 'enable' }, body: JSON.stringify(request.body) }); const taskId = result && result.output && result.output.task_id; if (!taskId) { throw new Error(`创建任务失败,响应中缺少 task_id: ${JSON.stringify(result)}`); } return result; } async function fetchTask(baseUrl, apiKey, taskId) { return requestJson(`${baseUrl}/api/v1/tasks/${encodeURIComponent(taskId)}`, { method: 'GET', headers: { Authorization: `Bearer ${apiKey}` } }); } async function callSyncGeneration(baseUrl, apiKey, request) { return requestJson(`${baseUrl}${request.endpoint}`, { method: 'POST', headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify(request.body) }); } ``` ### Technical Analysis The script allows `DASHSCOPE_BASE_URL` or `config.baseUrl` to replace the default Alibaba Cloud endpoint. The value is converted to a string and has a trailing slash removed, but it is not otherwise validated. There is no enforcement of: - The HTTPS protocol - An official DashScope hostname - An approved destination port - The absenc ...[truncated 2416 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the configured endpoint using `new URL()` and reject malformed URLs. 2. Require `url.protocol === "https:"`. 3. Allowlist the exact official DashScope hostnames required for supported regions. Avoid substring-based hostname checks. 4. Reject embedded usernames, passwords, fragments, and unexpected ports. 5. Do not forward the DashScope API key to custom endpoints. If custom gateways are required, require explicit opt-in and use a separate credential. 6. Disable automatic redirects for authenticated API requests where supported, or manually validate every redirect destination before resending the `Authorization` header. 7. Prefer `DASHSCOPE_API_KEY` or a secret manager over `config.json`. 8. If file-based key storage remains supported, document restrictive file permissions and ensure `config.json` is excluded from source control. 9. Add automated tests confirming that HTTP URLs, unapproved domains, deceptive subdomains, embedded credentials, and unexpected ports are rejected. A safe validation pattern should use exact hostname comparisons: ```js const ALLOWED_HOSTS = new Set([ 'dashscope.aliyuncs.com', 'dashscope-intl.aliyuncs.com' ]); function validateBaseUrl(value) { const url = new URL(value); if (url.protocol !== 'https:') { throw new Error('DashScope base URL must use HTTPS'); } if (!ALLOWED_HOSTS.has(url.hostname)) { throw new Error(`Unapproved DashScope hostname: ${url.hostname}`); } if (url.username || url.password || url.port || url.hash) { throw new Error('DashScope base URL contains prohibited components'); } return url.origin; } ``` The allowlist must be verified against current official Alibaba Cloud documentation before deployment. ]]>
