T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/lib/providers.mjs:294
- Finding
- Unrestricted Ark Base URL Can Exfiltrate API Credentials and Private Generation Inputs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/providers.mjs:294-301` **Vulnerability Type**: Unvalidated credential-bearing outbound request **Risk Level**: Medium ### Vulnerable Code ```js const base = env.ARK_BASE_URL || 'https://ark.cn-beijing.volces.com/api/v3' const body = { model: ark.model(), prompt: req.prompt, size: req.size || '2K', response_format: 'url', watermark: false, } if (req.images?.length) body.image = await Promise.all(req.images.map(asDataUri)) const j = await postJson(`${base}/images/generations`, body, { authorization: `Bearer ${env.ARK_API_KEY}` }, req.timeoutMs) ``` ### Technical Analysis The Ark provider accepts `ARK_BASE_URL` directly from the process environment without validating its protocol, hostname, port, or network destination. The resulting URL receives an authorization header containing `ARK_API_KEY`, as well as the generation prompt and any supplied reference images. Local images are converted into data URIs before transmission. Consequently, a malicious or mistakenly configured base URL can receive: - The Ark bearer credential. - User generation prompts. - Product or business imagery. - Model face-reference images or other potentially personal data. - Generation parameters and model identifiers. A custom endpoint can be legitimate when an organization deliberately uses a compatible gateway. However, forwarding an official provider credential and private input to any environment-controlled destination violates least-privilege principles. The implementation also permits an `http:` endpoint, which could expose the request to network interception. This issue requires an attacker to influence the process environment, deployment configuration, wrapper script, or command execution context. The code does not independently modify `ARK_BASE_URL`. ### Attack Path 1. An attacker compromises or influences a launcher, CI configuration, shell profile, deployment manifest, or wrapper that starts the ...[truncated 1472 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Require encrypted transport** - Parse the configured value with `new URL()`. - Reject every protocol except `https:`. - Reject URLs containing embedded usernames or passwords. 2. **Allowlist trusted destinations** - Use the official Ark hostname by default. - Restrict `ARK_BASE_URL` to an explicit allowlist of approved gateway hostnames. - Compare normalized hostnames rather than using substring or suffix checks that can be bypassed. 3. **Separate gateway credentials** - Never forward the official `ARK_API_KEY` to an arbitrary compatible gateway. - If custom gateways are required, introduce a separate gateway-specific credential variable. - Associate each credential with an approved destination. 4. **Protect internal network destinations** - Reject loopback, link-local, multicast, and private-network destinations unless an administrator explicitly approves them. - Resolve DNS and validate resulting addresses to reduce server-side request forgery and DNS-rebinding risks. 5. **Require explicit user awareness** - Display the normalized destination before sending private prompts or images to a non-default endpoint. - Require an explicit opt-in flag for custom providers or gateways. - Document that prompts and reference images leave the local system. 6. **Reduce credential exposure** - Use narrowly scoped keys with spending limits and rotation policies. - Revoke and rotate any key suspected of having been sent to an untrusted endpoint. - Avoid logging authorization headers or full provider error responses that could contain sensitive information. A hardened implementation should validate the endpoint before constructing the request, for example: ```js const officialBase = 'https://ark.cn-beijing.volces.com/api/v3' const parsed = new URL(env.ARK_BASE_URL || officialBase) if (parsed.protocol !== 'https:') { throw new Error('ARK_BASE_URL must use HTTPS') } const allowedH ...[truncated 373 chars]
