Back to skill

Security audit

Toutiao News Trends

Security checks for vulnerabilities and agentic risk

Overview

This skill fetches public Toutiao hot-list data as advertised, with only minor implementation hardening issues.

Install only if you are comfortable with the skill contacting Toutiao to fetch public trend data. Heavy or abnormal responses from the remote service could consume process memory, so adding response-size limits would be a useful hardening improvement.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/toutiao.js:65
Finding

Unbounded HTTP Response Buffering and Synchronous Decompression

Content
View full analysis
{ const chunks = []; res.on('data', (chunk) => chunks.push(chunk)); res.on('end', () => { try { const buffer = Buffer.concat(chunks); const decompressed = decompressBody(buffer, res.headers['content-encoding']); const text = decompressed.toString('utf-8'); const data = JSON.parse(text); resolve(data); } catch (e) { const status = res.statusCode || 0; reject(new Error(`Failed to parse JSON (status=${status}): ${e.message}`)); } }); }); ``` The decompression function invoked by this code uses synchronous decompression: ```js function decompressBody(buffer, contentEncoding) { if (!contentEncoding) return buffer; const encoding = String(contentEncoding).toLowerCase(); if (encoding.includes('gzip')) return zlib.gunzipSync(buffer); if (encoding.includes('deflate')) return zlib.inflateSync(buffer); if (encoding.includes('br')) return zlib.brotliDecompressSync(buffer); return buffer; } ``` ### Technical Analysis The HTTP response is accumulated in an in-memory array without a maximum byte limit. Once the response ends, all chunks are copied into a single buffer and potentially decompressed using synchronous zlib operations. A small compressed response can expand into a substantially larger decompressed payload. Because neither the compressed response nor the decompressed output has a configured size limit, an unexpectedly large response or compression bomb can consume excessive memory. The synchronous decompression methods also block the Node.js event loop until processing completes. The 15-second request timeout does not adequately mitigate this issue. It limits request duration but does not bound the number of bytes a ...[truncated 1714 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (1)

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The Accept-Language header is hard-coded to prefer zh-CN and zh for every request. This creates a locale policy issue because the script imposes a specific language preference without offering user opt-in or configuration, and the file does not document a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.