T09 · Insecure Skill Coding Practices
Error
- Location
- handler.js:145
- Finding
- API Credentials and User Data Can Be Sent to an Unrestricted or Insecure Endpoint<![CDATA[ ## Vulnerability Details **File Location**: `handler.js:145-163`, `handler.js:186-200`, `package.json:45-52`, `skill.yaml:25` **Vulnerability Type**: Unrestricted sensitive-data transmission **Risk Level**: High ### Vulnerable Code ```javascript async function discoverServices(capability, limit = 3) { if (!config.platform_url || !config.api_key) { throw new Error('[SkillForge] 未配置 platform_url 或 api_key'); } const category = CAPABILITY_CATEGORY_MAP[capability]; const url = new URL(`${config.platform_url}/v1/discover`); url.searchParams.set('capability', capability); if (category) { url.searchParams.set('category', category); } url.searchParams.set('limit', limit.toString()); try { const response = await fetch(url.toString(), { method: 'GET', headers: { 'Authorization': `Bearer ${config.api_key}`, 'Content-Type': 'application/json' } }); ``` ```javascript async function invokeService(serviceId, input, options = {}) { if (!config.platform_url || !config.api_key) { throw new Error('[SkillForge] 未配置 platform_url 或 api_key'); } const url = `${config.platform_url}/v1/services/${serviceId}/invoke`; try { const response = await fetch(url, { method: 'POST', headers: { 'Authorization': `Bearer ${config.api_key}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ input, options }) }); ``` The manifest also defines a plaintext default under a different configuration key: ```yaml config: apiUrl: ${SKILLFORGE_API_URL:-http://localhost:3000} timeout: 30000 ``` The runtime schema only requires a generic URI: ```json "platform_url": { "type": "string", "description": "SkillForge 平台地址", "format": "uri" } ``` ### Technical Analysis External network access and transmission of invocation input are necessary for the declared API-discovery functionality. However, the implementation does not constrain that access to ...[truncated 2069 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Require `https:` for all non-development endpoints and reject plaintext HTTP before initialization succeeds. 2. Maintain an explicit allowlist of approved SkillForge origins rather than accepting an arbitrary URI. 3. Normalize the configured URL and reject embedded credentials, unexpected ports, fragments, and ambiguous hostnames. 4. Disable automatic redirects or validate every redirect target before forwarding authorization headers. 5. Bind the API key to the expected platform audience and use a narrowly scoped, revocable token. 6. Add explicit user disclosure before transmitting prompts, files, or other potentially sensitive input. 7. Apply field-level filtering so internal metadata and secrets are not included in invocation payloads. 8. Standardize the configuration key across `skill.yaml`, `package.json`, documentation, and `handler.js`. 9. Add tests proving that HTTP URLs, non-allowlisted hosts, and cross-origin redirects are rejected. ]]>
