Back to skill

Security audit

X Trends Dev

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward CLI for fetching public X trend data, with some dependency and hardening issues but no evidence of hidden, persistent, credential-seeking, destructive, or deceptive behavior.

This skill appears reasonable to install if you want a small command-line trend scraper, but treat its output as third-party web content. Prefer a version with pinned/synchronized dependencies, updated vulnerable transitive packages, request timeouts, response-size limits, and terminal-output sanitization before using it in automated or shared environments.

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
index.js:48
Finding
Unbounded Response Buffering and Unsafe Terminal Rendering of Remote Content## Vulnerability Details **File Location**: `index.js:48-65, 74-87, 109-116` **Vulnerability Type**: Unbounded resource consumption and terminal control-sequence injection **Risk Level**: Medium ### Vulnerable Code ```js const fetchTrends = (targetUrl) => { return new Promise((resolve, reject) => { const req = https.get(targetUrl, { headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } }, (res) => { if (res.statusCode === 404) { reject(new Error(`Country '${countrySlug}' not found.`)); return; } if (res.statusCode !== 200) { reject(new Error(`Failed to fetch trends. Status Code: ${res.statusCode}`)); return; } let data = ''; res.on('data', (chunk) => data += chunk); res.on('end', () => resolve(data)); }); req.on('error', (e) => reject(e)); }); }; ``` ```js const html = await fetchTrends(url); const $ = cheerio.load(html); const trends = []; $('table.trends tbody tr').each((i, el) => { const name = $(el).find('.main a').text().trim(); const link = 'https://getdaytrends.com' + $(el).find('.main a').attr('href'); const volume = $(el).find('.desc').text().trim() || 'N/A'; if (name) { trends.push({ rank: i + 1, name, volume: volume.replace('Under ', '<'), link }); } }); ``` ```js slicedTrends.forEach((t) => { const rank = t.rank.toString().padStart(2, ' '); const name = t.name.length > 28 ? t.name.substring(0, 27) + '…' : t.name.padEnd(30); const volume = t.volume === 'N/A' ? chalk.gray(t.volume) : chalk.cyan(t.volume); console.log(`${chalk.gray(rank + '.')} ${chalk.white.bold(name)} ${volume.padStart(15)}`); }); ``` ### Technical Analysis The application trusts an external aggregator and buffers its entire HTTP response in a string without enforcing a maximum response size. It also does not configure ...[truncated 2126 chars]
Remediation
## Remediation Suggestions 1. Enforce a maximum response-body size and abort the request once the limit is exceeded. 2. Configure connection and socket timeouts using `req.setTimeout()` or an equivalent abort mechanism. 3. Validate that the response `Content-Type` is an expected HTML media type before parsing it. 4. Stop consuming or explicitly destroy responses rejected because of their HTTP status. 5. Strip ANSI escape sequences and nonessential control characters from all remotely sourced values before terminal output. 6. Apply explicit length limits to parsed names, volumes, links, and the number of table rows. 7. Validate extracted links with `new URL()` and require the expected HTTPS origin before including them in JSON output. 8. Handle aborted and premature response termination events so partial responses are not treated as successful. 9. Add tests covering oversized responses, stalled connections, malformed HTML, and control characters in remote fields. A hardened response handler should track accumulated bytes rather than relying only on string length, destroy the request when the configured limit is exceeded, and sanitize each remote field immediately after extraction.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Known Vulnerable Dependency: undici==7.19.2 — 16 advisory(ies): CVE-2026-1525 (Undici has an HTTP Request/Response Smuggling issue); CVE-2026-6733 (undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse); CVE-2026-1527 (Undici has CRLF Injection in undici via `upgrade` option) +13 more

High
Category
Supply Chain
Confidence
90% confidence
Finding
The lockfile pins `undici` to 7.19.2, and the supplied advisory list indicates multiple known high-severity issues in that version, including request/response smuggling, response queue poisoning, and CRLF injection. Because this skill fetches remote web content from public aggregators, it depends on HTTP client behavior; a vulnerable HTTP stack can expose requests to manipulation by malicious or compromised upstream servers, redirects, proxies, or intermediaries.

Vague Triggers

Low
Confidence
84% confidence
Finding
The manifest description says the skill can 'Scrape X trends for India and other countries with volume data,' which describes a broad capability but does not specify clear trigger phrases, scope boundaries, or exclusion conditions. In manifest files, this can create ambiguity about when the skill should activate, especially for generic requests about trends or countries.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"start": "node index.js"
  },
  "dependencies": {
    "chalk": "^5.3.0",
    "cheerio": "^1.0.0",
    "commander": "^12.0.0",
    "ora": "^8.0.0"
Confidence
95% confidence
Finding
Using caret ranges for dependencies allows future minor or patch releases to be installed automatically, which can introduce vulnerable or malicious upstream code through the software supply chain. In a scraping utility that relies on several third-party packages, this increases exposure to dependency compromise even though package.json alone does not prove active exploitation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "dependencies": {
    "chalk": "^5.3.0",
    "cheerio": "^1.0.0",
    "commander": "^12.0.0",
    "ora": "^8.0.0"
  },
Confidence
95% confidence
Finding
Using caret ranges for dependencies allows future minor or patch releases to be installed automatically, which can introduce vulnerable or malicious upstream code through the software supply chain. In a scraping utility that relies on several third-party packages, this increases exposure to dependency compromise even though package.json alone does not prove active exploitation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"dependencies": {
    "chalk": "^5.3.0",
    "cheerio": "^1.0.0",
    "commander": "^12.0.0",
    "ora": "^8.0.0"
  },
  "author": "Ani",
Confidence
95% confidence
Finding
Using caret ranges for dependencies allows future minor or patch releases to be installed automatically, which can introduce vulnerable or malicious upstream code through the software supply chain. In a scraping utility that relies on several third-party packages, this increases exposure to dependency compromise even though package.json alone does not prove active exploitation.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"chalk": "^5.3.0",
    "cheerio": "^1.0.0",
    "commander": "^12.0.0",
    "ora": "^8.0.0"
  },
  "author": "Ani",
  "license": "MIT"
Confidence
95% confidence
Finding
Using caret ranges for dependencies allows future minor or patch releases to be installed automatically, which can introduce vulnerable or malicious upstream code through the software supply chain. In a scraping utility that relies on several third-party packages, this increases exposure to dependency compromise even though package.json alone does not prove active exploitation.

Static analysis

No suspicious patterns detected.