T09 · Insecure Skill Coding Practices
- Location
scripts/generate.mjs:63- Finding
Untrusted Web Search Content Is Cached and Directly Exposed to the Agent
- Content
View full analysis
0) { // 提取搜索结果文本 const text = searchResult.content[0].text; console.log(`[Search] 找到结果`); return text; } ``` Search-result lines are selected using only length constraints: ```js const jokes = jokesResult .split('\n') .filter(line => line.length > 20 && line.length < 200) .slice(0, 2); jokes.forEach(joke => { items.push({ type: 'joke', content: joke.trim() }); }); ``` The same pattern is applied to meme content: ```js const lines = memesResult .split('\n') .filter(line => line.length > 10 && line.length < 150) .slice(0, 2); lines.forEach(line => { items.push({ type: 'meme', title: '网络热梗', content: line.trim() }); }); ``` It is also applied to chat-tip content: ```js const tips = tipsResult .split('\n') .filter(line => line.length > 30 && line.length < 200) .slice(0, 2); tips.forEach(tip => { items.push({ type: 'chat_tip', content: tip.trim() }); }); ``` The resulting external content is written to the persistent cache without validation or sanitization: ```js fs.writeFileSync(cacheFile, JSON.stringify(cache, null, 2)); ``` The cache is subsequently parsed and a randomly selected item is returned without validating its schema or content: ```js const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf-8')); ``` ```js const randomItem = cache.items[Math.floor(Math.random() * cache.items.length)]; return { success: true, item: random ...[truncated 3370 chars]- Remediation
View remediation
