T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/openclaw-hybrid-audit-changeway.js:1098
- Finding
- Threat-intelligence API responses are parsed incorrectly and failures are reported as successful scans<![CDATA[ ## Vulnerability Details **File Location**: `scripts/openclaw-hybrid-audit-changeway.js`, lines 1098-1146 **Vulnerability Type**: Fail-open API response handling **Risk Level**: Medium ### Vulnerable Code ```javascript doSignedPost(assessApiUrl, assessApiPath, { data: skillMetaList }, (err, apiResRaw) => { let intelHits = 0; let hitDetails = []; if (!err && apiResRaw) { try { let apiRes = JSON.parse(apiResRaw); if (apiRes.data && Array.isArray(apiRes.data)) { apiRes.data.forEach(item => { if (item.matched_intel && Array.isArray(item.matched_intel) && item.matched_intel.length > 0) { item.matched_intel.forEach(intel => { intelHits++; const maliciousDesc = intel.is_malicious === 1 || intel.is_malicious === '1' ? '存在恶意' : (intel.is_malicious === 0 || intel.is_malicious === '0' ? '不存在恶意' : '无标记'); hitDetails.push( `🚨 命中威胁情报: [${item.slug} ${item.version}] (Owner: ${item.author})\n` + ` 恶意判定: ${maliciousDesc} (原始 is_malicious: ${intel.is_malicious ?? '无标记'})\n` + ` 风险等级 (severity): ${intel.severity || 'UNKNOWN'}\n` + ` 情报详情: ${JSON.stringify(intel.info || {})}` ); }); } }); } } catch (parseErr) { hitDetails.push(`⚠️ API 响应解析失败: ${parseErr.message}`); } } else { hitDetails.push(`⚠️ 威胁情报 API 请求异常: ${err}`); } let finalDetailText = `${scannedSummary}\n\n>>> 威胁情报扫描结果:\n`; if (intelHits > 0) { finalDe ...[truncated 2471 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse only the response body: ```javascript const rawBody = typeof apiResRaw === 'string' ? apiResRaw : apiResRaw && typeof apiResRaw.body === 'string' ? apiResRaw.body : null; if (!rawBody) { appendSkip(itemNameSkill, 'Threat-intelligence response was unavailable', scannedSummary); return finalizeAndPushData(); } const apiRes = JSON.parse(rawBody); ``` 2. Validate that the decoded response matches the expected schema before using it. 3. Treat transport, HTTP, parsing, and schema errors as `FAIL` or `SKIP`, never as `PASS`. 4. Preserve the diagnostic error in the local report without exposing sensitive response content. 5. Add tests covering valid responses, malformed JSON, unexpected schemas, timeouts, non-2xx responses, and threat matches. 6. Ensure a successful result is emitted only after the server response has been parsed and assessed completely. ]]>
